JDK并发容器

JDK容器大部分在java.util.concurrent包中:

  • ConcurrentHashMap:线程安全的HashMap
    • HashMap线程不安全主要体现在多线程环境下扩容时会导致数据丢失或死循环。
    • 一个简单的方法是使用Collections.synchronizedMap(new HashMap()),这种方式底层原理是在HashMap之上利用synchronized封装一层线程同步机制,无论是对Map读写,都需要获取锁,会导致效率低下。
    • ConcurrentHashMap通过减小锁粒度实现效率上的提升。其内部细分为若干个(一般16个)小HashMap,称为段。当发生put时不同段的数据可以并行操作。然而当需要获取全局类信息如size时需要取得所有段的锁(事实上会先尝试无锁获取,失败时再执行所有锁机制),在size频繁调用场景下效率反而不如Collections.synchronizedMap(new HashMap())。
    • ConcurrentHashMap通过volatile实现了无锁读,当读取失败时会加锁重试。
  • CopyOnWriteArrayList
    • 适合读多写少场景
    • 写时会通过Arrays.copyOf复制一份数据,完成后替换旧数组,该操作通过ReentrantLock加锁
  • ConcurrentLinkedQueue
    • ConcurrentLinkedQueue是当前高并发场景中性能最好的线程安全队列。
    • 其底层通过cas实现无锁操作。
    • tail节点并不总是指向末尾,而是两次插入一更新
    • 当出队时,可能产生哨兵节点
    • 抢占节点时,当tail被更新会将当前节点指向tail,以减少节点遍历
public boolean offer(E e) {
        checkNotNull(e);
        final Node<E> newNode = new Node<E>(e);

        for (Node<E> t = tail, p = t;;) {
            Node<E> q = p.next;
            if (q == null) {
                // p is last node
                if (p.casNext(null, newNode)) {
                    // Successful CAS is the linearization point
                    // for e to become an element of this queue,
                    // and for newNode to become "live".
                    if (p != t) // hop two nodes at a time
                        casTail(t, newNode);  // Failure is OK.
                    return true;
                }
                // Lost CAS race to another thread; re-read next
            }
            else if (p == q)
                // We have fallen off list.  If tail is unchanged, it
                // will also be off-list, in which case we need to
                // jump to head, from which all live nodes are always
                // reachable.  Else the new tail is a better bet.
                p = (t != (t = tail)) ? t : head;
            else
                // Check for tail updates after two hops.
                p = (p != t && t != (t = tail)) ? t : q;
        }
    }
  • BlockingQueue
    • 阻塞式队列,适合用于数据共享通道
    • 主要实现有ArrayBlockingQueue、LinkedBlockingQueue
  • ConcurrentSkipListMap
    • 跳表主要用于数据快速查找
    • 相比于平衡树更新时只需更新局部数据,高并发下可以通过细粒度锁提高效率
    • 跳表定义了多层链表,高层链表是底层链表的子集
    • 内部主要由Node、Index、HeadIndex组成
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值