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

[Java并发编程-4] 集合的线程安全及其解决方法

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

[Java并发编程-4] 集合的线程安全及其解决方法

文章目录
    • 问题说明
    • List集合三种解决方案
      • Vector
      • Collections
      • CopyOnWriteArrayList
    • Set集合的解决方法

问题说明

jdk中修改集合(如List, Set等)的方法都没有使用synchronize关键字, 在线程使用直接调用这些方法会产生线程安全问题(即同时访问数据会出错), 所以称这些类/接口是线程不安全的

比如下面执行ArrayList的add方法(线程不安全的):

public class ListAdd{

    private static final List list = new ArrayList<>();

    public static void main(String[] args){
        for(int i = 0; i < 10; i ++){
            new Thread(() -> {
                list.add(1);
                System.out.println(list);
            }, "AAA").start();

            new Thread(() -> {
                list.add(2);
                System.out.println(list);
            }, "BBB").start();
        }
    }
}

结果有可能(也不一定)出现ConcurrentModificationException(并发修改)异常

List集合三种解决方案 Vector

来自jdk1.0古老的实现类, 在修改集合的方法(其他方法不需要使用)中使用了synchronize关键字

用Vector代替ArrayList,可以实现线程安全, 但是效率实在是太低了, 所以没啥人用

private static final List list = new Vector<>();
Collections

另一个古老的解决方法, 和第一个意思差不多, 用另一种方法取代ArrayList(用的也少):

private static final List list = Collections.synchronizedList(new ArrayList<>());

其实前面两种方法的原理都是实现了带有synchonize关键字的操作方法

CopyOnWriteArrayList

使用了一种叫读时共享, 写时复制的技术, 这可不是什么同步技术了

意思是每次修改集合L时时, 会复制生成一个与原来集合相同的集合L1, 然后对L1进行修改, 这时读还是读原来的集合L, 当修改完成时,将两个集合合并成修改之后的集合

这个使用的比较多

可以读读源码理解一下:

Set集合的解决方法

类似的, HashSet也会产生线程不安全问题, 也有类似的解决方法,就是CopyOnWriteHashSet

用法不多解释, 瓢葫芦画瓢罢了

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

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

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