美文网首页
并发容器基础

并发容器基础

作者: 我不懂我不懂a | 来源:发表于2020-11-16 21:48 被阅读0次

并发容器基础

LinkedBlockingQueue

线程安全:独占锁(阻塞队列)

容量:0x7ffffffff,可指定容量,可以说是有界阻塞队列

数据结构:单向链表

实现:

2*Node 队列头、队列尾
2*Lock 出队、入队锁
count(AtomicInteger) 元素个数
notEmpty、notFull 出队、入队操作线程等待队列

应用场景:

ArrayBlockingQueue

线程安全:独占锁(阻塞队列)

数据结构:有界数组

指定容量

实现:

数组items存放元素
全局独占lock,出队,入队,获取count都是加锁操作(锁粒度大)
takeIndex、putIndex 队头指针、队尾指针
*ps:有意思的是,只靠takeIndex和putIndex来看队头和队尾,它俩之间的就是元素。比如容量为10,takeIndex = 8, putIndex = 3, 那么元素列表下标就是[8,9,0,1,2,3];

notEmpty、notFull

应用场景:

疑问:

  • ArrayBlockingQueue和LinkedBlockingQueue的区别和适用场景? 为什么使用锁的方式不同,ArrayBlockingQueue要使用全局锁?使用出队、入队锁可不可以?

ConcurrentLinkedQueue

线程安全:CAS(非阻塞队列)
​无界
​数据结构:单向链表
实现:

由于offer、poll都是非阻塞CAS算法,并发情况下size函数并不是很有用

使用场景:

PriorityBlockingQueue

DelayQueue

CopyOnWriteArrayList

读操作无锁,写操作加锁

实现:

有个内部静态类COWSubList,是subList(int fromIndex, int toIndex)返回的结果

添加元素时,复制一个len + 1的数组,写入元素,然后替换原来的数组, setArray应该是原子的
* ps System.arrayCopy是浅拷贝
    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();
        }
    }

    final void setArray(Object[] a) {
        array = a;
    }

使用场景:读操作很多,写操作极少的并发场景。

ConcurrentHashMap

相关文章

网友评论

      本文标题:并发容器基础

      本文链接:https://www.haomeiwen.com/subject/lipubktx.html