目录
显示
线程安全的方式是建立了list的包装类
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<T>(list) :
new SynchronizedList<T>(list));//根据不同的list类型最终实现不同的包装类。
}
其中,SynchronizedList对部分操作加上了synchronized关键字以保证线程安全。但其iterator()操作还不是线程安全的。部分SynchronizedList的代码如下:
public E get(int index) {
synchronized(mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized(mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized(mutex) {list.add(index, element);}
}
public ListIterator<E> listIterator() {
return list.listIterator();
// Must be manually synched by user 需要用户保证同步,否则仍然可能抛出ConcurrentModificationException
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user <span style="font-family: Arial, Helvetica, sans-serif;">需要用户保证同步,否则仍然可能抛出ConcurrentModificationException</span>
}
遍历
遍历需要加到synchronized中
返回由指定列表支持的同步(线程安全)列表。为了保证串行访问,对后备列表 的所有 访问都必须通过返回的列表完成,这一点至关重要。
用户在迭代返回的列表时必须手动同步它:
List list = Collections.synchronizedList(new ArrayList());
...
synchronized (list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
不遵循此建议可能会导致不确定的行为。
如果指定的列表是可序列化的,则返回的列表将是可序列化的。
形参:
list – 要“包装”在同步列表中的列表。
返回值:
指定列表的同步视图。
特性
- 读取 写入时线程安全
- 但是读取性能不如CopyOnWriteArrayList强.
- 遍历时不同步,所以遍历时的线程不安全.
💡Collections.synchronizedList则可以用在CopyOnWriteArrayList不适用,但是有需要同步列表的地方, 读写操作都比较均匀的地方。