同步容器类ConcurrentHashMap及CopyOnWriteArrayList
ConcurrentHashMap
Java5在java.util.concurrent包中提供了多种并发容器类来改进同步容器的性能。其中应用最为广泛的为ConcurrentHashMap,ConcurrentHashMap是一个线程安全的hash表。对于多线程的操作,介于HashMap和HashTable之间。内部采用“锁分段”机制替代HashTable的独占锁,进而提高性能。
关于ConcurrentHashMap的“锁分段”原理,可以参考http://blog.csdn.net/xuefeng0707/article/details/40834595#comments这篇博客。但是在Java8中,ConConCurrentHashMap内部实现原理为CAS算法。
java.util.concurrent包还提供了涉及用于多线程上下文中的Collection实现:ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList和CopyOnWriteArraySet。当期望许多线程访问一个给定conllection时,ConcurrentHashMap通常优于同步的HashMap,ConcurrentSkipListMap通常优于同步的TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList优于同步的ArrayList。
CopyOnWriteArrayList
1 package com.ccfdod.juc; 2 3 import java.util.Iterator; 4 import java.util.concurrent.CopyOnWriteArrayList; 5 6 /** 7 * CopyOnWriteArrayList/CopyOnWriteArraySet:“写入并复制” 8 * 注意:添加操作多时,效率低,因为每次添加时都会进行复制,开销非常大。并发迭代多时,可以选择使用,提高效率 9 */ 10 public class TestCopyOnWriteArrayList { 11 12 public static void main(String[] args) { 13 HelloThread ht = new HelloThread(); 14 15 for(int i = 0; i < 10; i++) { 16 new Thread(ht).start(); 17 } 18 } 19 } 20 21 class HelloThread implements Runnable { 22 //将list改为线程安全的 23 // private static List<String> list = Collections.synchronizedList(new ArrayList<String>()); 24 private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); 25 26 static { 27 list.add("AA"); 28 list.add("BB"); 29 list.add("CC"); 30 } 31 32 @Override 33 public void run() { 34 Iterator<String> it = list.iterator(); 35 36 while (it.hasNext()) { 37 System.out.println(it.next()); 38 //如果使用第18行的代码,因为迭代和添加操作的是同一个数据源,会产生并发修改异常 39 //当然除了21行使用CopyOnWriteArrayList外,使用迭代器的方法对数据进行crud也是可行的 40 list.add("DD"); 41 } 42 } 43 }