Collections.synchronizedCollection 同步方法 装饰模式

14年刚开始学习java时从简单的语法开始学习,当时还没有接触到synchronized和lock等同步方法,用的较多的就是集合Collections.synchronizedCollection进行同步的方案。

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 Collectionfinal Object mutex;     // Object on which to synchronizeSynchronizedCollection(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 Mapfinal Object      mutex;        // Object on which to synchronizeSynchronizedMap(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用于存放传入的collectionfinal Collection<E> c;  // Backing Collection//mutex 用于作为同步的锁final Object mutex;     // Object on which to synchronizeSynchronizedCollection(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@Overridepublic void forEach(Consumer<? super E> consumer) {synchronized (mutex) {c.forEach(consumer);}}@Overridepublic boolean removeIf(Predicate<? super E> filter) {synchronized (mutex) {return c.removeIf(filter);}}@Overridepublic Spliterator<E> spliterator() {return c.spliterator(); // Must be manually synched by user!}@Overridepublic Stream<E> stream() {return c.stream(); // Must be manually synched by user!}@Overridepublic 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@Overridepublic Spliterator<E> spliterator() {return c.spliterator(); // Must be manually synched by user!}@Overridepublic Stream<E> stream() {return c.stream(); // Must be manually synched by user!}@Overridepublic Stream<E> parallelStream() {return c.parallelStream(); // Must be manually synched by user!}//listpublic 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()); 
}

装饰模式请看文章装饰模式