【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使用的数据结构是数组。结构如下
View Code
运行结果(某一次)
说明:在程序中,有一个PutThread线程会每隔50ms就向CopyOnWriteArrayList中添加一个元素,并且两次使用了迭代器,迭代器输出的内容都是生成迭代器时,CopyOnWriteArrayList的Object数组的快照的内容,在迭代的过程中,往CopyOnWriteArrayList中添加元素也不会抛出异常。
五、总结
CopyOnWriteArrayList的源码很简单,其主要用到的快照的思路,使得在迭代的过程中,只是Object数组之前的某个快照,而不是最新的Object,这样可以保证在迭代的过程中不会抛出ConcurrentModificationException异常。谢谢各位园友的观看~
由于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异常。谢谢各位园友的观看~
相关文章推荐
- Capture - Face detection
- java 二次确认对话框
- Java Stub 研究学习(2)
- RxJava
- JAVA开发者工具更新中...
- LL(1)文法 JAVA
- 分析java程序中占用CPU过高的线程
- Java十年的发展轨迹和历史变迁
- 【解决方案】 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userHandler': Injection of resource dependencies failed;
- Timer和ScheduledThreadPoolExecutor的区别
- 你真的会用Retrofit2吗?Retrofit2完全教程
- 14.Java对象内存逃逸技术
- Spring-IoC的简单使用及bean的作用域属性
- 【Spring4揭秘 基础4】国际化--MessageSource
- 支付宝支付步骤
- myeclipse配置gradle插件
- MyEclipse设置JDK和JRE具体的应用版本
- 模版方法( Template Method) Java
- Java中的单例模式
- [leetcode-342]Power of Four(java)