并发编程下如何使用安全的集合


我们都是知道像常用的ArrayList、LinkedList、hashSet、hashMap等都是线程不安全的集合,在多线程下可能会出现 并发修改异常: ConcurrentModificationException,那没如何来使用线程安全的集合呢? vectorHashTable 就不说了,因为他虽然是线程安全的集合,但是实现方式是在底层方法上全都加了 Synchronized来修饰的,效率低。

线程安全的List

Collections工具类提供了创建线程安全的List的方法:

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

不过这里我们重点说JUC下的CopyOnWriteArrayList
CopyOnWrite:写入时复制思想,简称COW,是计算机程序设计领域的一种优化策略
创建方式:

List<String> list = new CopyOnWriteArrayList<>();

实现原理:
我们先阅读其源码了解下它是如何实现的。以下代码是向CopyOnWriteArrayList中add方法的实现(向CopyOnWriteArrayList里添加元素),可以发现在添加的时候是加了ReentrantLock 锁,并且是先Copy出副本添加,最后再赋值。

/**
     * Appends the specified element to the end of this list.
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e;
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}

读的时候不需要加锁,如果读的时候有多个线程正在向CopyOnWriteArrayList添加数据,读还是会读到旧的数据,因为写的时候不会锁住旧的List。

public E get(int index) {
    return get(getArray(), index);
}

线程安全的Set

Collections工具类提供了创建线程安全的Set的方法:

Set<String> set = Collections.synchronizedSet(new HashSet<>());

同上,JUC下有Set<String> set = new CopyOnWriteArraySet<>();
这里额外说下,hashSet 底层是什么?
其实hashSet底层就是用的hashMap的Key,而value就是一个用static和final修饰的object不变值。
在这里插入图片描述

线程安全的Map

Collections工具类提供了创建线程安全的Map的方法:

Collections.synchronizedMap(new HashMap<>());

这里可不能同上了,因为JDK并没有给我们提供“CopyOnWriteMap”,而是提供了一个ConcurrentHashMap

Map<String, String> map = new ConcurrentHashMap<>();

jdk1.7中ConcurrentHashMap相对于HashMap其实多了一个Segment 的的角色,它其实是一种可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色。
jdk1.8中放弃了Segment臃肿的分段锁设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现。

上一篇:JUC并发编程-8锁现象
下一篇:JUC中常用的三大辅助类

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值