Parte VII: definire il comportamento di un agente

Obiettivo di questa parte del corso è quella di definire le classi che permettono di specificare il/i compartamento/i di un agente. Ogni comportamento di un agente è eseguito all'interno di un thread ad esso dedicato. In JAM abbiamo due tipi di comportamento: uno ``ciclico'' ed uno ``semplice''. Il comportamento ciclico consiste nell'eseguire il codice specificato in un determinato metodo (action) in modo ripetitivo finchè non si ritiene il compito completato (specificato invocando un altro metodo, done). Il comportamento semplice consiste invece nell'eseguire il codice specificato in un determincato metodo (action) una volta sola.

Si definisca la classe astratta JAMBehaviour in modo che estenda la classe Thread e contenga i seguenti campi:

Si definiscano, inoltre, i seguenti metodi: Il costruttore della classe JAMBehavior inizializza il campo myAgent (prendendo l'opportuno valore da un parametro), impostra done a false.

Si definisca ora la classe astratta JAMWhileBehaviour. Questa classe estende la classe JAMBehaviour ed ridefinisce il metodo run di Thread (si veda anche la Figura 3). Poichè in questo caso il comportamento specificato è di tipo ciclico il contenuto di action deve essere eseguito sino a quando non si ritiene il comportamento completato. Il metodo run è qualcosa del tipo:

public void run() {
  while (!isDone())
    try {
      action();
    }
    catch (InterruptedException err) {
      if (isDone())
        return;
    }
}
Il metodo action può contenere delle invocazioni dei metodi receive e send di JAMAgent. Questi metodi possono far si che il thread sia messo in stato di wait in attesa di un messaggio o che la risorsa MessageBox si liberi. Se si invoca il metodo done con l'intenzione di far terminare l'esecuzione del thread (ad esempio, in seguito alla pressione del bottone destroy) in questi casi non ha alcun effetto, in quanto il thread non sta eseguendo alcun codice e quindi non può accorgersi se è stata richiesta la terminazione. A questo scopo si modifichi il metodo done appena definito in modo che oltre ad impostare il valore della variabile done a true invochi il metodo interrupt della classe Thread
public void done() {
  [...]
  interrupt();
}
in modo da permette di far uscire dallo stato di wait il thread corrente. La necessità di catturare l'eccezione di tipo InterruptedException è data dalla presenza di tale interrupt che fa uscire dalla wait il thread acendo lanciare alla wait tale eccezione che solo nella run dovrà essere catturato (mai prima!).

Si noti che nella piattaforma Java 2 i metodi stop, suspend e resume sono stati dichiarati deprecati. Lo schema della classe JAMWhileBehaviour è ispirata a quanto mostrato in [3, pagina 47 vecchia edizione, pagina 67 nuova edizione] e presenta una soluzione per permettere ad un thread di interrompere un altro thread senza ricorso al metodo stop.

Si definisca ora la classe astratta JAMSimpleBehaviour che ridefinisce il metodo run di Thread in modo che questo invochi in metodo action una sola volta e quindi il metodo done. Si noti che anche qui è necessario includere le due chiamate all'interno del costrutto try ... catch come per il caso della run di JAMWhileBehaviour.



Subsections
baldoni 2005-01-13