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 }