Una possibile soluzione alternativa è quella presentata qui di seguito. Anzichè dichiarare synchronized i metodi addUser, removeUser, send2All, send2U è possibile bloccare direttamente l'oggetto listOfMessageBox per lo stretto necessario. Nel caso dei metodi addUser e removeUser questo approccio non cambia di molto la precedente soluzione:
public Message addUser(User user) { sychronized (listOfMessageBox) { // esecuzioni delle istruzioni per aggiungere uno user } } public Message removeUser(User user) { sychronized (listOfMessageBox) { // esecuzioni delle istruzioni per rimuovere uno user } }Nel caso dei metodi send2All e send2U, però, la situazione è diversa. Anzichè porre in mutua esclusione tutto il processo di consegna è possibile effettuare un in mutua esclusione una copia della struttura dati listOfMessageBox in un array (per mezzo del metodo toArray() di java.util.List) e quindi, percorrere questa copia della stuttura dati per la consegna del messaggio:
public Message send2All(Message4All message) { MessageBox[] arrayOfMessageBox; sychronized (listOfMessageBox) { arrayOfMessageBox = listOfMessageBox.toArray(); } // l'operazione di invio e` fatta percorrendo la copia locale // anziche` listOfMessageBox for (int i = 0; i < a.length; i++) { // consegna del messaggio in arrayOfMessageBox[i] } } public Message send2U(Message4U message) { MessageBox[] arrayOfMessageBox; sychronized (listOfMessageBox) { arrayOfMessageBox = listOfMessageBox.toArray(); } // l'operazione di invio e` fatta percorrendo la copia locale // anziche` listOfMessageBox for (int i = 0; i < a.length; i++) { // consegna del messaggio in arrayOfMessageBox[i] } }In questo modo due consegne di un messaggio possono essere effettuate anche contemporaneamente (con la garanzia comunque che due writeMessage sulla stessa MessageBox sono eseguite in mutua esclusione), mentre se durante la consegna di un messaggio un utente verrà rimosso questa operazione non altera la copia locale arrayOfMessageBox, evitanto una eccezione di tipo ConcurrentModificationException che invece sarebbe sollevata nel caso che percorressimo direttamente la struttura dati listOfMessageBox mediante un iteratore.
È importante notare che le implementazioni di List, LinkedList e ArrayList non sono sincronizzate (si veda la descrizione delle classi LinkedList e ArrayList in [3]). È quindi necessario creare le relative implementazioni di List nel seguente modo:
List list = Collections.synchronizedList(new LinkedList(...)); List list = Collections.synchronizedList(new ArrayList(...));