美文网首页
线程安全-并发容器J.U.C

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

作者: 墨平语凡 | 来源:发表于2018-06-03 10:54 被阅读0次

    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有序,支持更高的并发

    summary1.png summary2.png

    相关文章

      网友评论

          本文标题:线程安全-并发容器J.U.C

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