多线程下如何使用List集合
- 使用
Collections.synchronizedArrayList(),在集合增删改操作上加synchronized锁。默认使用的是当前对象(即创建的synchronized集合),也可以传入要锁的对象。 - 使用
CopyOnWriteArrayList类进行读写分离:
写时复制,当添加元素时,不直接在原数组上添加,而是先copy数组,复制出一个新容器,然后再新容器中加入元素,添加完元素再将引用指向新容器,这样可以并发的读,而不会读写互斥、提高效率。
但是写时还是要加锁,保证只有一个线程在进行写操作。
为了保证写线程替换数组后对其他读线程立即可见:array数组使用volatile进行修饰。
/** The lock protecting all mutators */final transient ReentrantLock lock = new ReentrantLock();/** The array, accessed only via getArray/setArray. */private transient volatile Object[] array;
public E set(int index, E element) {final ReentrantLock lock = this.lock;lock.lock(); // 加锁 保证写操作的并发安全try {Object[] elements = getArray();E oldValue = get(elements, index);if (oldValue != element) {int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len);newElements[index] = element;setArray(newElements);} else {// Not quite a no-op; ensures volatile write semanticssetArray(elements);}return oldValue;} finally {lock.unlock();}}
