栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JDK源码】解决ArrayList线程不安全

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JDK源码】解决ArrayList线程不安全

ArrayList 在并发情况下是不安全的!
为什么不安全?【JDK源码】ArrayList

解决方案:

1、切换成Vector就是线程安全的啦!

public class ListTest {
    public static void main(String[] args) {
        List arrayList = new Vector<>();
    }
}
 

Vector的add方法,Vector比ArrayList更早出现,所以Vector只是其中一种解决办法

2、使用工具类 Collections.synchronizedList(new ArrayList<>());

public class ListTest {
    public static void main(String[] args) {

        List arrayList = Collections.synchronizedList(new ArrayList<>());

    }
}
 

3、使JUC中的包:List arrayList = new CopyOnWriteArrayList<>();

public class ListTest {
    public static void main(String[] args) {

        List arrayList = new CopyOnWriteArrayList<>();

    }
}
 

CopyOnWriteArrayList:写入时复制! COW 计算机程序设计领域的一种优化策略 ,提高效率

多个线程调用的时候,list,读取的时候,是固定的,写入(存在覆盖操作);在写入的时候避免覆盖,造成数据错乱的问题;

CopyOnWriteArrayList比Vector厉害在哪里?

Vector 底层是使用synchronized关键字来实现的:效率特别低下。

CopyonWriteArrayList 使用的是Lock锁,效率会更加高效!

  • CopyOnWriteArrayList是一个线程安全的ArrayList,其实现原理是读写分离
其对写操作使用`ReentrantLock`来上锁,对读操作则不加锁;
CopyOnWriteArrayList在写操作的时候,会将list中的数组拷贝一份副本,然后对其副本进行操作(如果此时其他线程需要读的事,那么其他线程读取的是原先的没有修改的数组
如果其他写操作的线程要进行写操作,需要等待正在写的线程操作完成,释放ReentrantLock后,去获取锁才能进行写操作),写操作完成后,会将list中数组的地址引用指向修改后的新数组地址
如果使用场景的写操作十分频繁的话,建议还是不要实现CopyOnWriteArrayList,因为其添加的时候会造成数组的不断扩容和复制,十分消耗性能,会消耗内存
如果原数组的数据比较多的情况下,可能会导致young gc或者full gc;并且其不能使用在实时读的场景,在写操作过程中是要花费时间的,读取的时候可能还是旧数据;
CopyOnWriteArrayList 合适读多写少的场景
如果我们在使用的时候没法保证CopyOnWriteArrayList 到底要放多少数据的话,我们还是要谨慎使用,如果数据稍微有点多,每次写操作都重新拷贝数组,其代价实在太高昂了


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号