线程安全-并发容器J.U.C

ArrayList -> CopyOnWriteArrayList
当有新元素添加到CopyOnWriteArrayList的时候,先从原有的数组里拷贝一份出来,然后在新的数组上做些操作,写完之后再将原来的数组指向新的数组 。整个的add操作都是在写的保护下进行的,避免在多线程并发下进行add操作时复制出多个数组出来,把数据搞乱
缺点:消耗内存; 不能用于实时读的操作
适合读多写少的场景
设计思想:读写分离、最终结果一致性
读操作时在原数组上进行,不需要加锁,写操作时加锁

add操作加锁源码

 /**
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        synchronized (lock) {
            Object[] elements = getArray();
            int len = elements.length;
            if (index > len || index < 0)
                throw new IndexOutOfBoundsException(outOfBounds(index, len));
            Object[] newElements;
            int numMoved = len - index;
            if (numMoved == 0)
                newElements = Arrays.copyOf(elements, len + 1);
            else {
                newElements = new Object[len + 1];
                System.arraycopy(elements, 0, newElements, 0, index);
                System.arraycopy(elements, index, newElements, index + 1,
                                 numMoved);
            }
            newElements[index] = element;
            setArray(newElements);
        }
    }

get不加锁源码

 /**
     * {@inheritDoc}
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        return elementAt(getArray(), index);
    }

HashSet -> CopyOnWriteArraySet
线程安全的,底层实现是用到了CopyOnWriteArrayList,适合于大小较小的list集合,只读大于写操作的场景,因为需要复制整个数组,所以开销,迭代器不支持remove操作

TreeSet -> ConcurrentSkipListSet
支持自然排序,基于Map集合,多个线程可以并发执行add,remove等操作,但是对于批量操作如addAll,removeAll等不能保证以原子方式执行因为底层还是调用单次的add等操作,只能保证每一次的操作是原子性的,批量操作需要手动加锁

HashMap -> ConcurrentHashMap

TreeMap -> ConcurrentSkipListMap
key有序,支持更高的并发

线程安全-并发容器J.U.C_第1张图片
summary1.png
线程安全-并发容器J.U.C_第2张图片
summary2.png

你可能感兴趣的:(线程安全-并发容器J.U.C)