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

📄 agent.java

📁 JADE(JAVA Agent开发框架)是一个完全由JAVA语言开发的软件,它简化了多Agent系统的实现。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	 @see jade.core.Agent#setEnabledO2ACommunication(boolean enabled, int queueSize)
	 */
	public Object getO2AObject() {
		
		// Return 'null' if object-to-agent communication is disabled
		if(o2aQueue == null)
			return null;
		
		CondVar cond = null;
		Object result = null;
		synchronized (o2aQueue) {
			if(o2aQueue.isEmpty())
				return null;
			
			// Retrieve the first object from the object-to-agent
			// communication queue
			result = o2aQueue.remove(0);
			
			// If some thread issued a blocking putO2AObject() call with this
			// object, wake it up. cond.set is synchronized on CondVar object
			cond = (CondVar)o2aLocks.remove(result);
		}
		
		if(cond != null) {
			cond.set();
		}
		
		return result;
		
	}
	
	
	/**
	 This method declares this agent attitude towards object-to-agent
	 communication, that is, whether the agent accepts to communicate
	 with other non-JADE components living within the same JVM.
	 <br>
	 <b>NOT available in MIDP</b>
	 <br>
	 @param enabled Tells whether Java objects inserted with
	 <code>putO2AObject()</code> will be accepted.
	 @param queueSize If the object-to-agent communication is enabled,
	 this parameter specifiies the maximum number of Java objects that
	 will be queued. If the passed value is 0, no maximum limit is set
	 up for the queue.
	 
	 @see jade.wrapper.Agent#putO2AObject(Object o, boolean blocking)
	 @see jade.core.Agent#getO2AObject()
	 
	 */
	public void setEnabledO2ACommunication(boolean enabled, int queueSize) {
		if(enabled) {
			if(o2aQueue == null)
				o2aQueue = new ArrayList(queueSize);
			
			// Ignore a negative value
			if(queueSize >= 0)
				o2aQueueSize = queueSize;
		}
		else {
			
			// Wake up all threads blocked in putO2AObject() calls
			Iterator it = o2aLocks.values().iterator();
			while(it.hasNext()) {
				CondVar cv = (CondVar)it.next();
				if (cv != null) cv.set();
			}
			
			o2aQueue = null;
		}
		
	}
	//#MIDP_EXCLUDE_END
	
	
	//#APIDOC_EXCLUDE_BEGIN
	
	/**
	 This method is the main body of every agent. It 
	 provides startup and cleanup hooks for application 
	 programmers to put their specific code into.
	 @see jade.core.Agent#setup()
	 @see jade.core.Agent#takeDown()
	 */
	public final void run() {
		try {
			myLifeCycle.init();
			while (myLifeCycle.alive()) {
				try {
					myLifeCycle.execute();
					// Let other agents go on
					Thread.yield();
				}
				catch (JADESecurityException jse) {
					// FIXME: maybe we should send a message to the agent
					System.out.println("JADESecurityException: "+jse.getMessage());
				}
				catch (InterruptedException ie) {
					// Change LC state request from the outside. Just do nothing
					// and let the new LC state do its job
				}
				catch (InterruptedIOException ie) {
					// Change LC state request from the outside. Just do nothing
					// and let the new LC state do its job
				}
				catch (Interrupted i) {
					// Change LC state request from the outside. Just do nothing
					// and let the new LC state do its job
				}
			}
		}
		catch(Throwable t) {
			System.err.println("***  Uncaught Exception for agent " + myName + "  ***");
			t.printStackTrace();
		}
		terminating = true;
		myLifeCycle.end();
	}		
	//#APIDOC_EXCLUDE_END
	
	
	
	/**
	 Inner class ActiveLifeCycle
	 */
	private class ActiveLifeCycle extends LifeCycle {
		private static final long serialVersionUID = 11111;
		private ActiveLifeCycle() {
			super(AP_INITIATED);
		}
		
		public void setState(int s) {
			myState = s;
		}
		
		public void init() {
			setActiveState(AP_ACTIVE);
			//#MIDP_EXCLUDE_BEGIN
			notifyStarted();
			//#MIDP_EXCLUDE_END
			setup();
			restarting = false;
		}
		
		public void execute() throws JADESecurityException, InterruptedException, InterruptedIOException {
			// Select the next behaviour to execute
			Behaviour currentBehaviour = myScheduler.schedule();
			// Remember how many messages arrived
			int oldMsgCounter = messageCounter;
			
			// Just do it!
			currentBehaviour.actionWrapper();
			
			// If the current Behaviour has blocked and more messages arrived
			// in the meanwhile, restart the behaviour to give it another chance
			if((oldMsgCounter != messageCounter) && (!currentBehaviour.isRunnable())) {
				currentBehaviour.restart();
			}
			
			// When it is needed no more, delete it from the behaviours queue
			if(currentBehaviour.done()) {
				currentBehaviour.onEnd();
				myScheduler.remove(currentBehaviour);
				currentBehaviour = null;
			}
			else {
				synchronized(myScheduler) {
					// Need synchronized block (Crais Sayers, HP): What if
					// 1) it checks to see if its runnable, sees its not,
					//    so it begins to enter the body of the if clause
					// 2) meanwhile, in another thread, a message arrives, so
					//    the behaviour is restarted and moved to the ready list.
					// 3) now back in the first thread, the agent executes the
					//    body of the if clause and, by calling block(), moves
					//   the behaviour back to the blocked list.
					if(!currentBehaviour.isRunnable()) {
						// Remove blocked behaviour from ready behaviours queue
						// and put it in blocked behaviours queue
						myScheduler.block(currentBehaviour);
						currentBehaviour = null;
					}
				}
			}
		}
		
		public void end() {
			clean(false);
		}
		
		public boolean transitionTo(LifeCycle to) {
			// We can go to whatever state unless we are terminating
			if (!terminating) {
				// The agent is going to leave this state. When 
				// the agent will enter this state again it must be 
				// in AP_ACTIVE
				myState = AP_ACTIVE;
				return true;
			}
			else {
				return false;
			}
		}
		
		public void transitionFrom(LifeCycle from) {
			activateAllBehaviours();
		}
		
		public boolean isMessageAware() {
			return true;
		}
	} // END of inner class ActiveLifeCycle
	
	
	/**
	 Inner class DeletedLifeCycle
	 */
	private class DeletedLifeCycle extends LifeCycle {
		private static final long serialVersionUID = 11112;
		private DeletedLifeCycle() {
			super(AP_DELETED);
		}
		
		public void end() {
			clean(true);
		}
		
		public boolean alive() {
			return false;
		}		
	} // END of inner class DeletedLifeCycle
	
	//#MIDP_EXCLUDE_BEGIN
	/**
	 Inner class SuspendedLifeCycle
	 */
	private class SuspendedLifeCycle extends LifeCycle {
		private static final long serialVersionUID = 11113;
		private SuspendedLifeCycle() {
			super(AP_SUSPENDED);
		}
		
		public void execute() throws JADESecurityException, InterruptedException, InterruptedIOException {
			waitUntilActivate();
		}
		
		public void end() {
			clean(false);
		}
		
		public boolean transitionTo(LifeCycle to) {
			// We can only die or resume
			return (to.getState() == AP_ACTIVE || to.getState() == AP_DELETED); 
		}		
	} // END of inner class SuspendedLifeCycle
	
	//#MIDP_EXCLUDE_END
	
	
	//#APIDOC_EXCLUDE_BEGIN
	public void clean(boolean ok) {
		if (!ok) {
			System.out.println("ERROR: Agent " + myName + " died without being properly terminated !!!");
			System.out.println("State was " + myLifeCycle.getState());
		}
		//#MIDP_EXCLUDE_BEGIN
		// Reset the interrupted state of the Agent Thread
		Thread.interrupted();
		//#MIDP_EXCLUDE_END
		
		myBufferedLifeCycle = myLifeCycle;
		myLifeCycle = myActiveLifeCycle;
		takeDown();
		pendingTimers.clear();
		myToolkit.handleEnd(myAID);
		myLifeCycle = myBufferedLifeCycle;
	}
	//#APIDOC_EXCLUDE_END
	
	/**
	 This protected method is an empty placeholder for application
	 specific startup code. Agent developers can override it to
	 provide necessary behaviour. When this method is called the agent
	 has been already registered with the Agent Platform <b>AMS</b>
	 and is able to send and receive messages. However, the agent
	 execution model is still sequential and no behaviour scheduling
	 is active yet.
	 
	 This method can be used for ordinary startup tasks such as
	 <b>DF</b> registration, but is essential to add at least a
	 <code>Behaviour</code> object to the agent, in order for it to be
	 able to do anything.
	 @see jade.core.Agent#addBehaviour(Behaviour b)
	 @see jade.core.behaviours.Behaviour
	 */
	protected void setup() {}
	
	/**
	 This protected method is an empty placeholder for application
	 specific cleanup code. Agent developers can override it to
	 provide necessary behaviour. When this method is called the agent
	 has not deregistered itself with the Agent Platform <b>AMS</b>
	 and is still able to exchange messages with other
	 agents. However, no behaviour scheduling is active anymore and
	 the Agent Platform Life Cycle state is already set to
	 <em>deleted</em>.
	 
	 This method can be used for ordinary cleanup tasks such as
	 <b>DF</b> deregistration, but explicit removal of all agent
	 behaviours is not needed.
	 */
	protected void takeDown() {}
	
	//#MIDP_EXCLUDE_BEGIN
	/**
	 * This empty placeholder shall be overridden by user defined agents 
	 * to execute some actions before the original agent instance on the 
	 * source container is stopped (e.g. releasing local resources such 
	 * as a GUI).<br>
	 * <b>IMPORTANT:</b> At this point, it is ensured that the move process
	 * is successful and that a moved agent instance has been created on the 
	 * destination container 
	 * Therefore setting the value of a class field in this method will have
	 * no impact on the moved agent instance. Such parameters must indeed be 
	 * set <b>before</b> the <code>doMove()</code> method is called.
	 <br>
	 <b>NOT available in MIDP</b>
	 <br>
	 */
	protected void beforeMove() {}
	
	/**
	 Actions to perform after moving. This empty placeholder method can be
	 overridden by user defined agents to execute some actions just after
	 arriving to the destination agent container for a migration.
	 <br>
	 <b>NOT available in MIDP</b>
	 <br>
	 */
	protected void afterMove() {}
	
	/**
	 * This empty placeholder method shall be overridden by user defined agents 
	 * to execute some actions before copying an agent to another agent container.
	 * <br>
	 * <b>NOT available in MIDP</b>
	 * <br>
	 * @see beforeMove()
	 * @see afterClone()
	 */
	protected void beforeClone() {}
	
	/**
	 Actions to perform after cloning. This empty placeholder method can be
	 overridden by user defined agents to execute some actions just after
	 creating an agent copy to the destination agent container.
	 <br>
	 <b>NOT available in MIDP</b>
	 <br>
	 */
	protected void afterClone() {}
	//#MIDP_EXCLUDE_END
	
	// This method is used by the Agent Container to fire up a new agent for the first time
	// Mutual exclusion with itself and Agent.addPlatformAddress()
	synchronized void powerUp(AID id, Thread t) {
		if (myThread == null) {
			// Set this agent's name and address and start its embedded thread
			myName = id.getLocalName();
			myHap = id.getHap();
			
			myAID = id;
			myToolkit.setPlatformAddresses(myAID);
			
			myThread = t;
			myThread.start();
		}
	}
	
	//#J2ME_EXCLUDE_BEGIN
	// Return agent thread
	// Package scooped as it is called by JadeMisc add-on for container monitor purpose
	Thread getThread() {
		return myThread;
	}
	//#J2ME_EXCLUDE_END
	
	//#MIDP_EXCLUDE_BEGIN
	private void writeObject(ObjectOutputStream out) throws IOException {
		// Updates the queue maximum size field, before serialising
		msgQueueMaxSize = msgQueue.getMaxSize();
		
		out.defaultWriteObject();
	}
	
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		in.defaultReadObject();
		
		// Restore transient fields (apart from myThread, which will be set when the agent will be powered up)
		msgQueue = new MessageQueue(msgQueueMaxSize);
		stateLock = new Object();
		suspendLock = new Object();
		pendingTimers = new AssociationTB();
		theDispatcher = TimerDispatcher.getTimerDispatcher();
		// restore O2AQueue
		if (o2aQueueSize > 0) 
			o2aQueue = new ArrayList(o2aQueueSize);
		o2aLocks = new HashMap();
		myToolkit = DummyToolkit.instance();
		
		//#PJAVA_EXCLUDE_BEGIN
		//For persistence service
		persistentPendingTimers = new java.util.HashSet();
		//#PJAVA_EXCLUDE_END
	}
	//#MIDP_EXCLUDE_END
	
	
	/**
	 This method is executed when blockingReceive() is called
	 from a separate Thread. 
	 It does not affect the agent state.
	 */
	private void waitUntilWake(long millis) {
		synchronized(msgQueue) {
			try {
				// Blocks on msgQueue monitor for a while
				waitOn(msgQueue, millis);
			}
			catch (InterruptedException ie) {
				throw new Interrupted();
			}
		}
	}
	
	//#MIDP_EXCLUDE_BEGIN
	private void waitUntilActivate() throws InterruptedException {
		synchronized(suspendLock) {

⌨️ 快捷键说明

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