ho deciso di scavare nel codice sorgente un po 'e ho notato che Collections.synchronizedList(List)
viene implementato come segue:È sicuro iterare su wrapper sincronizzati?
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<T>(list) :
new SynchronizedList<T>(list));
}
in cui la classe annidata SynchronizedList
è:
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
public boolean More ...equals(Object o) {
synchronized(mutex) {return list.equals(o);}
}
//ommited
public void add(int index, E element) {
synchronized(mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized(mutex) {return list.remove(index);}
}
//rest is ommited
}
Come si fanno ammirare, la classe useses un private
bloccare l'oggetto per garantire la sicurezza del thread. Ma the documentation ci permette di iterare su di esso utilizzando il blocco sull'oggetto restituito dal metodo factory.
E 'indispensabile che l'utente sincronizzare manualmente sul restituita lista quando l'iterazione su di esso:
Quindi, usiamo diverse serrature per l'iterazione e la modifica di lista (add
, remove
, ecc).
Perché è considerato sicuro?
_Quindi, utilizziamo diversi blocchi per l'iterazione e la modifica della lista_ Che cosa ti fa pensare così? –
@SotiriosDelimanolis Il codice sorgente che ho citato. Nella classe nidificata usiamo sincronizzato (mutex) che non è accessibile dall'esterno. –