【Java并发】并发容器笔记

  • 同步容器和并发容器

非线程安全的容器:ArrayList、LinkedList、HashMap等等

同步容器:Vector、Stack、HashtableCollections.synchronizedXxx()等等

并发容器:ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet等等

同步容器和并发容器的区别:

同步容器使用synchronized进行同步,它的操作是按顺序执行的,并发性很差;并发容器使用不同的锁机制实现了高并发的访问,可以并发的对容器进行遍历及写入;并且它不会抛出ConcurrentModificationException异常。

  • ConcurrentHashMap:代替同步的HashMap。它并不是简单的使用互斥锁,它的锁的粒度更细(分段锁),可以并发的进行读写操作而不是向Hashtable那样加锁只能一个线程访问。

  • ConcurrentHashMap的size()和isEmpty()返回的是近似值(但是一般是准确的),因为这俩货都需要对Map进行整个的遍历,在遍历过程中不能保证size和isEmpty的正确性。但是在并发环境下,因为容器内容会不断变化,所以就牺牲它俩来提供更好的并发性能。

  • CopyOnWriteArrayList:即“写入时复制”,用来代替同步的List。大概意思就是在对List进行写操作时,在内部复制一份对象,然后对这个副本进行操作。

  • ConcurrentHashMap都不会抛出ConcurrentModficationException

ConcurrentHashMap举例:

新建两个线程,一个对ConcurrentHashMap进行写入操作,另一个进行不断遍历操作。

public class ConcurrentHashMapTest {
private static ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
public static void main(String[] args) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            int i=0;
            while (true){
                map.put("key"+i,i++);
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                for(String key : map.keySet()){
                    System.out.println("key="+key+",value="+map.get(key));
                }
                System.out.println("-----");
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}
}

输出:

然而如果将ConcurrentHashMap换成HashMap或者是同步的Hashtabled都会抛出ConcurrentModificationException异常。因为HashMap不是线程安全的,而虽然Hashtable是线程安全定,但是它并不支持在多线程下进行并发的访问,仍然需要手都同步。

原文地址:https://www.cnblogs.com/cnsec/p/13286714.html