Il thread per la gestione del ciclo LIL per un certo user può essere attivato contestualmente all'aggiunta dello user nella chat room (metodo addUser di ChatRoom) e terminare alla rimozione dello user dalla chat room (metodo removeUser di ChatRoom).
Il ciclo LIL ha il compito di controllare continuamente il MessageBox del suo client ed inviare i messaggi in esso inseriti dai cicli REIR di altri client (si veda la Figura 5).
Se non vi sono messaggi in coda il thread che gestisce il ciclo LIL deve essere messo in attesa dell'inserimento di un messaggio. A tale fine è necessario modificare il metodo readMessage di MessageBox introducento una wait():public synchronized Message readMessage() throws InteruptedException { while (box.isEmpty()) wait(); // operazione di lettura }Il thread è svegliato non appena un messaggio viene inserito nella coda di messaggi. A tale fine è necessario modificare il metodo writeMessage di MessageBox:
public synchronized void writeMessage(Message message) { // operazione di scrittura notifyAll(); }
Per ogni oggetto MessageBox presente nella chat room è quindi necessario attivare un thread contenente il ciclo LIL, si definisca quindi una classe MessageBoxWithThreadLIL che estende MessageBox ed implementa Runnable contenente i campi:
public void run() { while (!stopRequested) try { // leggi un messaggio del controllato messageBox // e invialo al client out. writeObjet(this.readMessage()); } catch (InterruptedException err) { if (stopRequested) return; } }Si noti che in effetti il comando ReceiveCRC non è utilizzato nella soluzione suggerita, si è liberi di trovare soluzioni alternative se lo si desidera.
Infine è necessario modificare il metodo addUser al fine di creare un oggetto di tipo MessageBoxWithThreadLIL anzichè un semplice MessageBox:
public void addUser(User user, ObjectOutput out) { synchronized(listOfMessageBox) { MessageBox mb = new MessageBoxWithThreadLIL(user, out); // aggiunta di mb in listOfMessageBox } }Si noti che lo stream di output di oggetti out può essere passato al metodo addUser attraverso il parametro opzionale del metodo execCRC del comando GetIntoRoomCRC dove la addUser è invocata. Cioè lo schema del metodo run della classe ThreadREIR dovrebbe diventare:
public void run() { boolean stopRequested = false; Message message; ChatRoomCommand command; while (!stopRequested) { // leggi un comando da `in' if (comando instaceof GetIntoRoomCRC) message = comando.execCRC(chatRoom, out); else message = comando.execCRC(chatRoom, null); // scrivi message su `out' if (comando instanceof ExitRoom) stopRequested = true; } }
In modo analogo la rimozione di uno user deve prevvedere anche all'interruzione dell'esecuzione del thread attivo presso un MessageBox:
public void removeUser(User user) { synchronized(listOfMessageBox) { MessageBoxWithThreadLIL mb; // cerca la casella di user e ponila in mb mb.requestedStop(); // rimuovi la casella di user da listOfMessageBox } }