并发容器基础

2020-11-16  本文已影响0人  我不懂我不懂a

并发容器基础

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

应用场景:

疑问:

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

上一篇 下一篇

猜你喜欢

热点阅读