14年刚开始学习java时从简单的语法开始学习,当时还没有接触到synchronized和lock等同步方法,用的较多的就是集合Collections.synchronizedCollection进行同步的方案。
上面的synchronizedXXX函数接收特定的Collection,将转换成包装类型的SynchronizedXXX类型。
//SynchronizedList继承自SynchronizedCollection实现了list接口
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
//SynchronizedSet继承自SynchronizedCollection实现了set接口
static class SynchronizedSet<E>
extends SynchronizedCollection<E>
implements Set<E> {
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) {
this.c = Objects.requireNonNull(c);
mutex = this;
}
//SynchronizedMap实现了map接口,内部和SynchronizedCollection实现方式类似
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L;
private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize
SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
}
可以看到最终的方案都和SynchronizedCollection一样,下面就分析SynchronizedCollection:
//装饰模式
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
//c用于存放传入的collection
final Collection<E> c; // Backing Collection
//mutex 用于作为同步的锁
final Object mutex; // Object on which to synchronize
SynchronizedCollection(Collection<E> c) {
//判断不为null就赋值
this.c = Objects.requireNonNull(c);
mutex = this;
}
//可以指定同步用到的锁
SynchronizedCollection(Collection<E> c, Object mutex) {
this.c = Objects.requireNonNull(c);
this.mutex = Objects.requireNonNull(mutex);
}
//每个操作都添加同步(synchronized)
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 Object[] toArray() {
synchronized (mutex) {return c.toArray();}
}
public <T> T[] toArray(T[] a) {
synchronized (mutex) {return c.toArray(a);}
}
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);}
}
public boolean containsAll(Collection<?> coll) {
synchronized (mutex) {return c.containsAll(coll);}
}
public boolean addAll(Collection<? extends E> coll) {
synchronized (mutex) {return c.addAll(coll);}
}
public boolean removeAll(Collection<?> coll) {
synchronized (mutex) {return c.removeAll(coll);}
}
public boolean retainAll(Collection<?> coll) {
synchronized (mutex) {return c.retainAll(coll);}
}
public void clear() {
synchronized (mutex) {c.clear();}
}
public String toString() {
synchronized (mutex) {return c.toString();}
}
// Override default methods in Collection
@Override
public void forEach(Consumer<? super E> consumer) {
synchronized (mutex) {c.forEach(consumer);}
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
synchronized (mutex) {return c.removeIf(filter);}
}
@Override
public Spliterator<E> spliterator() {
return c.spliterator(); // Must be manually synched by user!
}
@Override
public Stream<E> stream() {
return c.stream(); // Must be manually synched by user!
}
@Override
public Stream<E> parallelStream() {
return c.parallelStream(); // Must be manually synched by user!
}
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {s.defaultWriteObject();}
}
}
利用装饰模式根据传入的Collection生成特定同步的SynchronizedCollection,生成的集合每个同步操作都是持有mutex这个锁,所以再进行操作时就是线程安全的集合了。
注意:
SynchronizedCollection和其他的SynchronizedXXX集合在获取迭代器时都没有进行同步,所以需要用户手动进行同步,放置其他线程修改集合。
//collection
@Override
public Spliterator<E> spliterator() {
return c.spliterator(); // Must be manually synched by user!
}
@Override
public Stream<E> stream() {
return c.stream(); // Must be manually synched by user!
}
@Override
public Stream<E> parallelStream() {
return c.parallelStream(); // Must be manually synched by user!
}
//list
public ListIterator<E> listIterator() {
return list.listIterator(); // Must be manually synched by user
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}
List list = Collections.synchronizedList(new ArrayList());
... synchronized(list) {
Iterator i = list.iterator();
while (i.hasNext()) foo(i.next());
}
装饰模式请看文章装饰模式