java中CopyOnWriteArrayList是线程安全的吗?
下文是笔者采用示例验证CopyOnWriteArraylist是否为线程安全的?
CopyOnWriteArrayList是线程安全的
CopyOnWriteArrrayList的实现原理
1. CopyOnWriteArrayList实现了List接口,因此它是一个队列。
2. CopyOnWriteArrayList包含了成员lock。
每一个CopyOnWriteArrayList都和一个监视器锁lock绑定,
通过lock,实现了对CopyOnWriteArrayList的互斥访问。
3. CopyOnWriteArrayList包含了成员array数组,
这说明CopyOnWriteArrayList本质上通过数组实现的。
4.CopyOnWriteArrayList的“动态数组”机制
它内部有个“volatile数组”(array)来保持数据。在“添加/修改/删除”数据时
都会新建一个数组,并将更新后的数据拷贝到新建的数组中
最后再将该数组赋值给“volatile数组”。这就是它叫做CopyOnWriteArrayList的原因
CopyOnWriteArrayList就是通过这种方式实现的动态数组
不过正由于它在“添加/修改/删除”数据时,都会新建数组,所以涉及到修改数据的操作
CopyOnWriteArrayList效率很 低;但是单单只是进行遍历查找的话,效率比较高。
5.CopyOnWriteArrayList的“线程安全”机制 -- 是通过volatile和监视器锁Synchrnoized来实现的。
6.CopyOnWriteArrayList是通过“volatile数组”来保存数据的
一个线程读取volatile数组时,总能看到其它线程对该volatile变量最后的写入
通过volatile提供了“读取到的数据总是最新的”这个机制的 保证。
7.CopyOnWriteArrayList通过监视器锁Synchrnoized来保护数据
在“添加/修改/删除”数据时,会先“获取监视器锁”
再修改完毕之后,先将数据更新到“volatile数组”中
然后再“释放互斥锁”
采用此种方法,可使数据更安全
例:
package com.java265;
import java.util.concurrent.CopyOnWriteArrayList;
public class TestJUC {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


