JDK并发数据结构

作者: 城市里永远的学习者 | 来源:发表于2018-09-28 15:48 被阅读0次

    一、并发list
    Vector和CopyOnWriteArrayList是两个线程安全的list,如果在多线程环境中使用ArrayList则使用Collections.synchronizedList(List list)进行包装。但两者实现的机制不同:
    Vector的get和add/remove等操作都是采用synhronized同步方法,都需要获得对象锁,并发时会影响性能
    代码块:

    /*get 采用同步方法*/
    public synchronized E get(int index) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            return elementData(index);
        }
    
    /*set采用同步方法*/
     public synchronized E set(int index, E element) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }
    

    CopyOnWriteArrayList利用了对象的不变性,读操作时没有加锁,在试图改变对象时,总是先获得对象的副本,然后对副本进行修改,最后将副本写回,写操作时用的重入锁
    代码块:

    /*get方法*/
    private E get(Object[] a, int index) {
            return (E) a[index];
        }
    
    /*set方法采用ReentrantLock锁*/
     public E set(int index, E element) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                E oldValue = get(elements, index);
    
                if (oldValue != element) {
                    int len = elements.length;
                    Object[] newElements = Arrays.copyOf(elements, len);
                    newElements[index] = element;
                    setArray(newElements);
                } else {
                    // Not quite a no-op; ensures volatile write semantics
                    setArray(elements);
                }
                return oldValue;
            } finally {
                lock.unlock();
            }
        }
    

    对比:1.读操作时,CopyOnWriteArrayList更快 2.写操作时,Vector会比起快,CopyOnWriteArrayList首先申请了锁,同时还要进行对象副本复制

    二、并发set
    与list类似,set也有一个CopyOnWriteArraySet,实现set接口,也是线程安全的。适合读多写少的高并发场景,高并发写场景使用Collections 的方法:
    public static <T> Set<T> synchronizedSet(Set<T> s) 得到一个线程安全的set

    三、并发map
    多线程环境一般使用Collections.synchronizedMap()得到一个线程安全的map,但在高并发情况,使用java.concurrent包中的ConcurrentMap的子类ConcurrentHashMap,其get方法是无锁的,put等操作采用分段锁机制,从而提高其操作性能,而hashMap则是非线程安全的

    四、并发queue
    两种:BlockingQueue(以此为接口的阻塞队列)和ConcurrentLinkedQueue(高性能队列),但都继承自queue。
    高并发场景下使用ConcurrentLinkedQueue队列,而BlockingQueue用于简化线程间的数据共享

    五、并发deque
    并发双堆队列

    相关文章

      网友评论

        本文标题:JDK并发数据结构

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