測試代碼:
package copyOnWriteArrayListTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class AddThread implements Runnable {
private List<Double> list;
public AddThread(List<Double> list) {
this.list = list;
}
@Override
public void run(){
for ( int i = 0; i < 10000; i++){
list.add(Math.random());
}
}
}
public class CopyOnWriteArrayListTest {
public static final int THREAD_POOL_SIZE = 2;
public static void main(String[] args) throws InterruptedException {
// List<Double> list = new ArrayList<>();
List<Double> list = new CopyOnWriteArrayList<>();
ExecutorService es = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
es.execute(new AddThread(list));
es.execute(new AddThread(list));
es.shutdown();
Thread.sleep(4000);
System.out.println("OK, list length: " + list.size());
}
}
輸出結果:
OK, list length: 20000
如果把支持寫時拷貝的list替換成普通的ArrayList:
List list = new ArrayList<>();
因爲兩個線程同時對這個普通的ArrayList進行寫操作,結果如下:
OK, list length: 17578
看下CopyOnWriteArrayList實現源代碼裏Add方法的實現:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1);
es[len] = e;
setArray(es);
return true;
}
}
lock初始化的地方:
final transient Object lock = new Object();