您的位置:首页 > 编程语言 > Java开发

【JUC】JDK1.8源码分析之CopyOnWriteArrayList(六)

2016-06-01 10:44 911 查看
一、前言

  由于Deque与Queue有很大的相似性,Deque为双端队列,队列头部和尾部都可以进行入队列和出队列的操作,所以不再介绍Deque,感兴趣的读者可以自行阅读源码,相信偶了Queue源码的分析经验,Deque的分析也会水到渠成,下面介绍List在JUC下的CopyOnWriteArrayList类,CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。

二、CopyOnWriteArrayList数据结构

  通过源码分析可知,CopyOnWriteArrayList使用的数据结构是数组。结构如下

package com.hust.grid.leesf.collections;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

class PutThread extends Thread {
private CopyOnWriteArrayList<Integer> cowal;

public PutThread(CopyOnWriteArrayList<Integer> cowal) {
this.cowal = cowal;
}

public void run() {
try {
for (int i = 100; i < 110; i++) {
cowal.add(i);
Thread.sleep(50);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class CopyOnWriteArrayListDemo {
public static void main(String[] args) {
CopyOnWriteArrayList<Integer> cowal = new CopyOnWriteArrayList<Integer>();
for (int i = 0; i < 10; i++) {
cowal.add(i);
}
PutThread p1 = new PutThread(cowal);
p1.start();
Iterator<Integer> iterator = cowal.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}

iterator = cowal.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}


View Code
  运行结果(某一次) 

0 1 2 3 4 5 6 7 8 9 100
0 1 2 3 4 5 6 7 8 9 100 101 102 103


  说明:在程序中,有一个PutThread线程会每隔50ms就向CopyOnWriteArrayList中添加一个元素,并且两次使用了迭代器,迭代器输出的内容都是生成迭代器时,CopyOnWriteArrayList的Object数组的快照的内容,在迭代的过程中,往CopyOnWriteArrayList中添加元素也不会抛出异常。

五、总结

  CopyOnWriteArrayList的源码很简单,其主要用到的快照的思路,使得在迭代的过程中,只是Object数组之前的某个快照,而不是最新的Object,这样可以保证在迭代的过程中不会抛出ConcurrentModificationException异常。谢谢各位园友的观看~

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: