⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agent.java

📁 JADE(JAVA Agent开发框架)是一个完全由JAVA语言开发的软件,它简化了多Agent系统的实现。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************
 JADE - Java Agent DEvelopment Framework is a framework to develop 
 multi-agent systems in compliance with the FIPA specifications.
 Copyright (C) 2000 CSELT S.p.A. 
 
 GNU Lesser General Public License
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation, 
 version 2.1 of the License. 
 
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the
 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA  02111-1307, USA.
 *****************************************************************/

package jade.core;

import java.io.IOException;
import java.io.InterruptedIOException;

import jade.util.leap.Serializable;
import jade.util.leap.Iterator;
import java.util.Hashtable;
import java.util.Enumeration;

import jade.core.behaviours.Behaviour;

import jade.lang.acl.*;

import jade.security.JADESecurityException;

//#MIDP_EXCLUDE_BEGIN
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

import jade.core.mobility.AgentMobilityHelper;
import jade.core.mobility.Movable;

import jade.util.leap.List;
import jade.util.leap.ArrayList;
import jade.util.leap.Map;
import jade.util.leap.HashMap;
//#MIDP_EXCLUDE_END

/*#MIDP_INCLUDE_BEGIN
 import javax.microedition.midlet.*;
 #MIDP_INCLUDE_END*/

/**
 The <code>Agent</code> class is the common superclass for user
 defined software agents. It provides methods to perform basic agent
 tasks, such as:
 <ul>
 <li> <b> Message passing using <code>ACLMessage</code> objects,
 both unicast and multicast with optional pattern matching. </b></li>
 <li> <b> Complete Agent Platform life cycle support, including
 starting, suspending and killing an agent. </b></li>
 <li> <b> Scheduling and execution of multiple concurrent activities. </b></li>
 </ul>
 
 Application programmers must write their own agents as
 <code>Agent</code> subclasses, adding specific behaviours as needed
 and exploiting <code>Agent</code> class capabilities.
 
 @author Giovanni Rimassa - Universita' di Parma
 @author Giovanni Caire - TILAB
 @version $Date: 2007-06-14 11:02:43 +0200 (gio, 14 giu 2007) $ $Revision: 5969 $
 */
public class Agent implements Runnable, Serializable 
//#APIDOC_EXCLUDE_BEGIN
, TimerListener 
//#APIDOC_EXCLUDE_END
{
	private static final long     serialVersionUID = 3487495895819000L;
	
	/**
	 Inner class Interrupted.
	 This class is used to handle change state requests that occur
	 in particular situations such as when the agent thread is 
	 blocked in the doWait() method.
	 */
	public static class Interrupted extends Error {
		public Interrupted() {
			super();
		}
	}  // END of inner class Interrupted
	
	
	/**
	 Inner class AssociationTB.
	 This class manages bidirectional associations between Timer and
	 Behaviour objects, using hash tables. This class is 
	 synchronized with the operations
	 carried out by the TimerDispatcher. It allows also to avoid a deadlock when:
	 1) A behaviour blocks for a very short time --> A Timer is added
	 to the TimerDispatcher
	 2) The Timer immediately expires and the TimerDispatcher try to 
	 restart the behaviour before the pair (b, t) is added to the 
	 pendingTimers of this agent.
	 */
	private class AssociationTB {
		private Hashtable BtoT = new Hashtable();
		private Hashtable TtoB = new Hashtable();
		
		public void clear() {
			synchronized (theDispatcher) {
				Enumeration e = timers();
				while (e.hasMoreElements()) {
					Timer t = (Timer) e.nextElement();
					theDispatcher.remove(t);
				}
				
				BtoT.clear();
				TtoB.clear();
				
				//#J2ME_EXCLUDE_BEGIN
				
				// For persistence service
				persistentPendingTimers.clear();
				
				//#J2ME_EXCLUDE_END
			} //end synch
		}
		
		public void addPair(Behaviour b, Timer t) {
			TBPair pair = new TBPair(Agent.this, t, b);
			addPair(pair);
		}
		
		public void addPair(TBPair pair) {
			synchronized (theDispatcher) {
				if(pair.getOwner() == null) {
					pair.setOwner(Agent.this);
				}
				
				pair.setTimer(theDispatcher.add(pair.getTimer()));
				TBPair old = (TBPair)BtoT.put(pair.getBehaviour(), pair);
				if(old != null) {
					theDispatcher.remove(old.getTimer());
					//#J2ME_EXCLUDE_BEGIN
					persistentPendingTimers.remove(old);
					//#J2ME_EXCLUDE_END
					TtoB.remove(old.getTimer());
				}
				// Note that timers added to the TimerDispatcher are unique --> there
				// can't be an old value to handle
				TtoB.put(pair.getTimer(), pair);
				
				//#J2ME_EXCLUDE_BEGIN
				// For persistence service
				persistentPendingTimers.add(pair);
				//#J2ME_EXCLUDE_END
			} //end synch
		}
		
		public void removeMapping(Behaviour b) {
			synchronized (theDispatcher) {
				TBPair pair = (TBPair)BtoT.remove(b);
				if(pair != null) {
					TtoB.remove(pair.getTimer());
					
					//#J2ME_EXCLUDE_BEGIN
					// For persistence service
					persistentPendingTimers.remove(pair);
					//#J2ME_EXCLUDE_END
					
					theDispatcher.remove(pair.getTimer());
				}
			} //end synch
		}
		
		
		public Timer getPeer(Behaviour b) {
			// this is not synchronized because BtoT is an Hashtable (that is already synch!)
			TBPair pair = (TBPair)BtoT.get(b);
			if(pair != null) {
				return pair.getTimer();
			}
			else {
				return null;
			}
		}
		
		public Behaviour getPeer(Timer t) {
			// this is not synchronized because BtoT is an Hashtable (that is already synch!)
			TBPair pair = (TBPair)TtoB.get(t);
			if(pair != null) {
				return pair.getBehaviour();
			}
			else {
				return null;
			}
		}
		
		private Enumeration timers() {
			return TtoB.keys();
		}
		
		
	} // End of inner class AssociationTB 
	
	/** Inner class TBPair
	 *
	 */
	private static class TBPair {
		
		public TBPair() {
			expirationTime = -1;
		}
		
		public TBPair(Agent a, Timer t, Behaviour b) {
			owner = a;
			myTimer = t;
			expirationTime = t.expirationTime();
			myBehaviour = b;
		}
		
		public void setTimer(Timer t) {
			myTimer = t;
		}
		
		public Timer getTimer() {
			return myTimer;
		}
		
		public Behaviour getBehaviour() {
			return myBehaviour;
		}
		
		public void setBehaviour(Behaviour b) {
			myBehaviour = b;
		}
		
		
		public Agent getOwner() {
			return owner;
		}
		
		public void setOwner(Agent o) {
			owner = o;
			createTimerIfNeeded();
		}
		
		public long getExpirationTime() {
			return expirationTime;
		}
		
		public void setExpirationTime(long when) {
			expirationTime = when;
			createTimerIfNeeded();
		}
		
		// If both the owner and the expiration time have been set,
		// but the Timer object is still null, create one
		private void createTimerIfNeeded() {
			if(myTimer == null) {
				if((owner != null) && (expirationTime > 0)) {
					myTimer = new Timer(expirationTime, owner);
				}
			}
		}  
		
		private Timer myTimer;
		private long expirationTime;
		private Behaviour myBehaviour;
		private Agent owner;
		
	} // End of inner class TBPair 
	
	
	//#MIDP_EXCLUDE_BEGIN
	/**
	 Inner class CondVar
	 A simple class for a boolean condition variable
	 */
	private static class CondVar {
		private boolean value = false;
		
		public synchronized void waitOn() throws InterruptedException {
			while(!value) {
				wait();
			}
		}
		
		public synchronized void set() {
			value = true;
			notifyAll();
		}
		
	} // End of inner class CondVar 
	//#MIDP_EXCLUDE_END
	
	
	//#APIDOC_EXCLUDE_BEGIN
	
	/**
	 Schedules a restart for a behaviour, after a certain amount of
	 time has passed.
	 @param b The behaviour to restart later.
	 @param millis The amount of time to wait before restarting
	 <code>b</code>.
	 @see jade.core.behaviours.Behaviour#block(long millis)
	 */
	public void restartLater(Behaviour b, long millis) {
		if (millis <= 0) 
			return;
		Timer t = new Timer(System.currentTimeMillis() + millis, this);
		pendingTimers.addPair(b, t);
	}
	
	/**
	 Restarts the behaviour associated with t. 
	 This method runs within the time-critical Timer Dispatcher thread and
	 is not intended to be called by users. It is defined public only because
	 is part of the <code>TimerListener</code> interface.
	 */
	public void doTimeOut(Timer t) {
		Behaviour b = null;
		// This synchronized block avoids that if a behaviour is blocked 
		// again just after pendingTimers.getPeer(t) is called, a new mapping
		// is added before the old one is removed --> The new mapping is 
		// removed instead of the old one.
		// In any case b.restart() must be called outside the synchronized
		// block to avoid a deadlock between the TimerDispatcher and the Scheduler.
		synchronized (theDispatcher) {
			b = pendingTimers.getPeer(t);
			if(b != null) {
				pendingTimers.removeMapping(b);
			}
		}
		if(b != null) {
			b.restart();
		}
		else {
			System.out.println("Warning: No mapping found for expired timer "+t.expirationTime());
		}
	}
	
	/**
	 Notifies this agent that one of its behaviours has been restarted
	 for some reason. This method clears any timer associated with
	 behaviour object <code>b</code>, and it is unneeded by
	 application level code. To explicitly schedule behaviours, use
	 <code>block()</code> and <code>restart()</code> methods.
	 @param b The behaviour object which was restarted.
	 @see jade.core.behaviours.Behaviour#restart()
	 */
	public void notifyRestarted(Behaviour b) {
		// Did this restart() cause the root behaviour to become runnable ?
		// If so, put the root behaviour back into the ready queue.
		Behaviour root = b.root();
		if(root.isRunnable()) {
			myScheduler.restart(root);
		}
	}

	public void removeTimer(Behaviour b) {
		// The mapping for b in general has already been removed in doTimeOut().
		// There is however a case related to ParallelBehaviours where 
		// notifyRestarted() is not called as a consequence of a timer
		// expiration --> doTimeOut() is not called in this case -->
		// We remove the mapping in any case.
		Timer t = pendingTimers.getPeer(b);
		if(t != null) {
			pendingTimers.removeMapping(b);
		}
	}
	
	
	/**
	 Out of band value for Agent Platform Life Cycle states.
	 */
	public static final int AP_MIN = 0;   // Hand-made type checking
	
	/**
	 Represents the <em>initiated</em> agent state.
	 */
	public static final int AP_INITIATED = 1;
	
	/**
	 Represents the <em>active</em> agent state.
	 */
	public static final int AP_ACTIVE = 2;
	
	/**
	 Represents the <em>idle</em> agent state.
	 */
	public static final int AP_IDLE = 3;
	
	/**
	 Represents the <em>suspended</em> agent state.
	 */
	public static final int AP_SUSPENDED = 4;
	
	/**
	 Represents the <em>waiting</em> agent state.
	 */
	public static final int AP_WAITING = 5;
	
	/**
	 Represents the <em>deleted</em> agent state.
	 */
	public static final int AP_DELETED = 6;
	
	
	/**
	 Out of band value for Agent Platform Life Cycle states.
	 */
	public static final int AP_MAX = 13;    // Hand-made type checking
	
	//#MIDP_EXCLUDE_BEGIN  
	
	/**
	 These constants represent the various Domain Life Cycle states
	 */
	
	/**
	 Out of band value for Domain Life Cycle states.
	 */
	public static final int D_MIN = 9;     // Hand-made type checking
	
	/**
	 Represents the <em>active</em> agent state.
	 */
	public static final int D_ACTIVE = 10;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -