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

问题说明

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

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

public class ListAdd{

    private static final List<Integer> 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<Integer> list = new Vector<>();

Collections

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

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

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

CopyOnWriteArrayList

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

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

这个使用的比较多

可以读读源码理解一下:

img

Set集合的解决方法

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

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值