java并发编程实战读书笔记3

Posted 郭梧悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java并发编程实战读书笔记3相关的知识,希望对你有一定的参考价值。

1、ConcurrentModificationException 当容器在迭代过程中被其他线程修改时,就会抛出该异常。想要避免该以后该异常,就需要在迭代的过程中持有该容器的锁。但是长时间持有容器的锁会降低程序的可伸缩性,持有锁的时间越长,那么该锁的竞争就会越激烈,就会降低吞吐量和CPU的利用率。也可以克隆容器,在副本上操作避免出现此异常。比如Vector和Hashtable就可能抛出该异常。

2、Queue用来临时保存一组等待处理的元素,在Queue上操作不会阻塞。而BlockingQueue则扩展了Queue,插入和获取都是可阻塞的操作。如果队列为空,获取元素就会一直阻塞,如果队列满了,则插入操作就会一直阻塞。知道队列中出现可用的空间,“生产者和消费者”模式可以使用祖泽队列。

3、ConcurrentHashMap 与Vector和Hashtable不一样,Vector和Hashtable的每个方法都进行同步,使得每次只有一个线程能访问容器的状态。而ConcurrentHashMap采用了分段锁机制,使得任意数量的读取县城可以并发的访问Map,读线程和写线程可以并发的访问Map,并且一定数量的写入线程可以并发的修改Map。这意味着Hashtable和synchronizedMap在获取锁的时候可以防止其他线程访问这个Map进行独占访问,而ConcurrentHashMap并没有提供此特性。ConcurrentHashMap是不抛出ConcurrentModificationException异常的

4、只有当应用程序需要对Map加锁进行独占访问时,才应该放弃使用ConcurrentHashMap。

5、CopyOnWriteArrayList,写入时复制,也就是说其所有可变操作都是通过对底层数组进行一次新的复制来实现
,该容器在迭代期间不需要对容器进行枷锁或者复制。在每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。“写入时复制”容器的迭代器保留一个只想底层的技术数组的引用,因为他不会被修改,因此多个线程可以对此容器进行迭代,而不会彼此干扰或者与修改容器的线程相互干扰。注意该类也不会抛出ConcurrentModificationException异常。写入时复制,这一特性可以通过其add等方法来进行验证。


    public boolean add(E e) {
        synchronized (lock) {//注意进行了加锁
             //获取旧的eleemnts数组。
            Object[] elements = getArray();
            int len = elements.length;
            /将elements元素复制到一个新的数组中,并将e添加到新的数组中
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            //将新的数组替换旧的数组。
            setArray(newElements);
            return true;
        }
    }

   final Object[] getArray() {
        return elements;
    }

    /**
     * Sets the array.
     */
    final void setArray(Object[] a) {
        elements = a;
    }

因为对于数组的写操作都要复制一遍数组,在副本的基础上修改后改变elements的引用,可以发现如果数组元素太多的情况下使用该容器是何等的不智!该类适合使用的场景是读操作远远多于修改操作时。

以上是关于java并发编程实战读书笔记3的主要内容,如果未能解决你的问题,请参考以下文章

java并发编程实战读书笔记3

Java并发编程实战读书笔记之死锁

Java并发编程实战读书笔记之死锁

java并发编程实战读书笔记之FutureTask

java并发编程实战读书笔记之FutureTask

Java并发编程实战读书笔记