?? agent.java
字號:
/*****************************************************************
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 + -