Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
来源:互联网 发布:雍熙北伐 知乎 编辑:程序博客网 时间:2024/06/05 23:56
上1篇讲述了Java并发编程的第1个基本思想–CAS/乐观锁,这1篇接着讲述并发编程的第2个基本思想:CopyOnWrite
- CopyOnWrite基本思想
- CopyOnWriteArrayList
- CopyOnWriteArraySet
- AtomicReference的一个应用
- 总结
CopyOnWrite基本思想
CopyOnWrite,
顾名思义:就是在Write的时候,不直接Write源数据,而是把数据Copy一份出来改,改完之后,再通过悲观锁或者乐观锁的方式写回去。
那为什么不直接改,而是要拷贝一份改呢? 其实为了”读“的时候,不加锁!
下面就通过几个案例来展现CopyOnWrite的应用。
CopyOnArrayList
和ArrayList一样,CopyOnArrayList的核心数据结构,也是一个数组,如下:
- 1
- 1
下面是CopyOnArrayList的几个”读“函数:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
这些”读“函数,都没有加锁,那如何保证”线程安全“的呢?
答案就在”写“函数里面:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
其他“写”函数,比如remove, 和add类似,在此不在详述。
CopyOnArraySet
就是用Array实现的一个Set,保证所有元素都不重复。其内部就是封装的一个CopyOnArrayList
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
AtomicReference的一个应用
问题的提出:
一个NumberRange的对象,如下所示:
public class NumberRange
{
private int lower;
private int upper;public int getRange()
{
return upper - lower;
}
在多线程情况下,如何不加锁,实现该对象的线程安全?
错误的方法1:使用AtomicInteger
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
正确的方法:final + CopyOnWrite + 乐观锁
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
备注:把此问题推而广之,当我们想实现”不加锁,对一个大的对象实现线程安全访问时“, 就可利用CopyOnWrite + CAS乐观锁来达到同样的效果。
总结
CopyOnWrite的主要目的是实现“写”加锁,“读”不加锁,从而提高并发度。在上面例子中,CopyOnWriteArrayList使用了CopyOnWrite + 悲观锁; NumberRange使用了CopyOnWrite + 乐观锁。
- Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
- Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
- Java中的Copy-On-Write容器,CopyOnWriteArrayList和CopyOnWriteArraySet
- JUC源码分析24-队列-CopyOnWriteArrayList,CopyOnWriteArraySet
- 《Java源码分析》:CopyOnWriteArrayList/ CopyOnWriteArraySet
- 《Java源码分析》:CopyOnWriteArrayList/ CopyOnWriteArraySet
- Java多线程 -- JUC包源码分析10 -- ConcurrentLinkedQueue源码分析
- Java多线程 -- JUC包源码分析11 -- CyclicBarrier源码分析
- Java多线程 -- JUC包源码分析12 -- ThreadPoolExecutor源码分析
- Java多线程 -- JUC包源码分析16 -- Exchanger源码分析
- JAVA多线程 之 CopyOnWriteArrayList和CopyOnWriteArraySet
- Java多线程”JUC”集合中的CopyOnWriteArraySet
- Java多线程 -- JUC包源码分析1 -- CAS/乐观锁
- Java多线程 -- JUC包源码分析3-- volatile/final语义
- Java多线程 -- JUC包源码分析6 -- ConcurrentHashMap
- Java多线程 -- JUC包源码分析15 -- SynchronousQueue与CachedThreadPool
- Java多线程 -- JUC包源码分析19 -- ForkJoinPool/ForkJoinTask
- Java多线程 -- JUC包源码分析1 -- CAS/乐观锁
- 线程简介
- 集成springmvc和mybatis环境的Javaweb基础框架,省去新手搭建繁琐环境的苦恼
- 线程的创建和运行(未完待续)
- Thinking in BigData(八)大数据Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解
- 代码处理iOS的横竖屏旋转
- Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
- 跨进程通信AIDL的学习
- HDUOJ 4282 A very hard mathematic problem
- BroadcastReceiver中使用startActivity报错
- 设计模式初步
- Android Fragment和Activity
- htm5手机端实现拖动图片
- JeeSite用户指导
- <安彦>主流浏览器缓存机制