当前位置:首页 » JAVA技术教程

【Java源码解读】Collections.synchronizedXxx

2018-08-07 17:45 本站整理 浏览(6)

源码来源:OpenJDK 10

 

解读对象

  • synchronizedCollection(Collection<T> c)
  • synchronizedList(List<T> list)
  • synchronizedSet(Set<T> s)
  • synchronizedSortedSet(SortedSet<T> s)
  • synchronizedNavigableSet(NavigableSet<T> s)
  • synchronizedMap(Map<K, V> m)
  • synchronizedSortedMap(SortedMap<K,V> m)
  • synchronizedNavigableMap(NavigableMap<K,V> m)

 

Collections.synchronizedCollection(Collection<E> c)

该方法可以将一个Collection包装为同步(线程安全)的List。但是通过Iterator、Spliterator或Stream遍历这个新List时,需要在外部做好同步

 

Collection c = Collections.synchronizedCollection(myCollection);
synchronized (c) {
    Iterator i = c.iterator(); // Must be in the synchronized block
    while (i.hasNext())
        foo(i.next());
}

 

 

SynchronizedCollection

构造方法

SynchronizedCollection(Collection<E> c)

创建一个SynchronizedCollection,并将指定的集合c作为内部集合

此方法会将SynchronizedCollection实例本身作为互斥体(mutex)

 

SynchronizedCollection(Collection<E> c, Object mutex)

创建一个SynchronizedCollection,并将指定的集合作为内部集合,将指定的对象作为互斥体(mutex)

 

其它方法

SynchronizedCollection的以下方法都是对互斥体进行同步,再调用内部list实例上的相应方法:

size()

isEmpty()

contains(Object o)

toArray()

toArray(T[] a)

add(E e)

remove(Object o)

containsAll(Collection<?> coll)

addAll(Collection<? extends E> coll)

removeAll(Collection<?> coll)

retainAll(Collection<?> coll)

clear()

toString()

forEach(Consumer<? super E> consumer)

removeIf(Predicate<? super E> filter)

 

因为对ListIterator的线程安全式使用需要在外部额外的同步,所以以下3个方法没有同步的必要:

spliterator()

stream()

parallelStream()

 

Collections.synchronizedList(List<T> list)

  • 该方法可以将一个List包装为同步(线程安全)的List。但是通过Iterator、Spliterator或Stream遍历这个新List时,需要在外部做好同步(参照Collections.synchronizedCollection(Collection<E> c))。
  • 因为同步实现方式相同,所以包装后的List性能与Vector相当。
  • 如果原List是RandomAccess,该方法会用Collections.SynchronizedRandomAccessList类包装;
    • 否则就是用Collections.SynchronizedList类包装
      • RandomAccess是一个空接口,不包含任何方法。它主要用于标记List接口的实现类支持快速随机获取(通常指时间复杂度为O(1))。ArrayList就是RandomAccess,而LinkedList不是

 

SynchronizedList

此类继承自SynchronizedCollection,并实现List接口

 

构造方法

SynchronizedList(List<E> list)

创建一个SynchronizedList,并将指定的list作为内部列表

此方法会将SynchronizedList实例本身作为同步互斥体(mutex)

Collections.synchronizedList方法内部调用的就是此方法

 

SynchronizedList(List<E> list, Object mutex)

创建一个SynchronizedList,并将指定的list作为内部列表,将指定的对象作为同步互斥体(mutex)

 

其它方法

SynchronizedList的以下方法都是对互斥体进行同步,再调用内部list实例上的相应方法:

equals(Object o)

hashCode()

get(int index)

set(int index, E element)

add(int index, E element)

remove(int index)

indexOf(Object o)

lastIndexOf(Object o)

addAll(int index, Collection<? extends E> c)

replaceAll(UnaryOperator<E> operator)

sort(Comparator<? super E> c)

 

因为对ListIterator的线程安全式使用需要在外部额外的同步,所以以下2个方法没有同步的必要:

listIterator()

listIterator(int index)

 

subList(int fromIndex, int toIndex)

该方法也对互斥体进行了同步,并将内部list的subList方法返回的实例封装为SynchronizedList,且指定互斥体为原SynchronizedList的互斥体

(subList这类方法使用场景少,实现复杂,真的有些吃力不讨好)

 

SynchronizedRandomAccessList

此类继承自SynchronizedList,并实现RandomAccess接口

与SynchronizedList不同之处:subList的返回值是被包装成SynchronizedRandomAccessList

 

构造方法

SynchronizedRandomAccessList(List<E> list)

创建一个SynchronizedRandomAccessList;内部就是调用SynchronizedList(List<E> list)

Collections.synchronizedList方法内部调用的就是此方法

 

SynchronizedRandomAccessList(List<E> list, Object mutex)

创建一个SynchronizedRandomAccessList;内部就是调用SynchronizedList(List<E> list, Object mutex)