1.调用静态方法
public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
return new SynchronizedCollection<>(c);
}
2.初始化静态内部类SynchronizedCollection
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final Collection<E> c; // Backing Collection
final Object mutex; // Object on which to synchronize
SynchronizedCollection(Collection<E> c) {
if (c==null)
throw new NullPointerException();
this.c = c;
mutex = this;
}
SynchronizedCollection(Collection<E> c, Object mutex) {
this.c = c;
this.mutex = mutex;
}
public int size() {
synchronized (mutex) {return c.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return c.isEmpty();}
}
public boolean contains(Object o) {
synchronized (mutex) {return c.contains(o);}
}
......
public Iterator<E> iterator() {
return c.iterator(); // Must be manually synched by user!
}
public boolean add(E e) {
synchronized (mutex) {return c.add(e);}
}
public boolean remove(Object o) {
synchronized (mutex) {return c.remove(o);}
}
......
}
备注:内部类重写集合的所有方法,通过获得mutex的锁保证线程安全
唯一没有synchronized 代码块的是遍历方法,需要用户自己同步Must be manually synched by user!
细节:所有同步都是在方法内部,如果在所有方法上同步,只要该对象调用其中一个方法,就会拿到当前对象的锁,
该对象调用其他的方法只能阻塞,等待其释放锁,而在方法内部添加代码块可以有效避免此问题。