当前位置: 代码迷 >> 综合 >> 常用并发数据结构:CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap
  详细解决方案

常用并发数据结构:CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap

热度:124   发布时间:2023-10-15 07:03:50.0

并发数据结构:添加或删除

  • 阻塞式集合:当集合为空或满时,等待;
  • 非阻塞式集合:当集合为空或满时,不等待,返回null或抛出异常!

List

  • ArrayList:线程不安全;
  • Vector:线程安全,适合写多读少,效率低(几乎所有的读写操作都加了synchronized);
  • Collections.synchronizedList(...):线程安全,使用synchronized,效率低;
  • CopyOnWriteArrayList:线程安全,非阻塞的,适合读多写少,推荐使用;
public class ListTypeDemo {public static void main(String[] args) {// 线程不安全:ArrayListList<String> unsafeList = new ArrayList<String>();// 线程安全:Vector适合写多读少,性能差,不推荐使用List<String> safeList1 = new Vector<String>();// 线程安全:基于synchronized,效率差,不推荐使用List<String> safeList2 = Collections.synchronizedList(new ArrayList<String>());// 线程安全:CopyOnWriteArrayList非阻塞的(当集合为空或满时,返回NULL或抛出异常),适合读多写少// 推荐使用CopyOnWriteArrayListList<String> safeList3 = new CopyOnWriteArrayList<String>();ListThread t1 = new ListThread(unsafeList);ListThread t2 = new ListThread(safeList1);ListThread t3 = new ListThread(safeList2);ListThread t4 = new ListThread(safeList3);for (int i = 0; i < 10; i++) {new Thread(t1).start();}for (int i = 0; i < 10; i++) {new Thread(t2).start();}for (int i = 0; i < 10; i++) {new Thread(t3).start();}for (int i = 0; i < 10; i++) {new Thread(t4).start();}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("unsafeList.size() : " + unsafeList.size());System.out.println("safeList1.size() : " + safeList1.size());System.out.println("safeList2.size() : " + safeList2.size());System.out.println("safeList3.size() : " + safeList3.size());System.out.println("============分隔线============");System.out.println("unsafeList : " + unsafeList.toString());System.out.println("safeList1 : " + safeList1.toString());System.out.println("safeList2 : " + safeList2.toString());System.out.println("safeList3 : " + safeList3.toString());}
}class ListThread implements Runnable {private List<String> list;public ListThread(List<String> list) {this.list = list;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}
}

输出结果展示:

常用并发数据结构:CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap

Set

  • HashSet:线程不安全;
  • Collections.synchronizedSet(...):线程安全,使用synchronized,效率低;
  • CopyOnWriteArraySet:线程安全,非阻塞,适合读多写少,推荐使用;
public class SetTypeDemo {public static void main(String[] args) {// 线程不安全:HashSetSet<String> unsafeSet = new HashSet<String>();// 线程不安全:TreeSet,对Set集合中的元素进行排序,是线程不安全的Set<String> unsafeSet2 = new TreeSet<String>();// 线程安全:Set<String> safeSet1 = Collections.synchronizedSet(new HashSet<String>());// 线程安全:CopyOnWriteArraySet,非阻塞,适合读多写少// 推荐使用Set<String> safeSet2 = new CopyOnWriteArraySet<String>();SetThread t1 = new SetThread(unsafeSet);SetThread t2 = new SetThread(unsafeSet2);SetThread t3 = new SetThread(safeSet1);SetThread t4 = new SetThread(safeSet2);for (int i = 0; i < 10; i++) {new Thread(t1,String.valueOf(i)).start();}for (int i = 0; i < 10; i++) {new Thread(t2,String.valueOf(i)).start();}for (int i = 0; i < 10; i++) {new Thread(t3,String.valueOf(i)).start();}for (int i = 0; i < 10; i++) {new Thread(t4,String.valueOf(i)).start();}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("unsafeSet.size() : " + unsafeSet.size());System.out.println("unsafeSet2.size() : " + unsafeSet2.size());System.out.println("safeSet1.size() : " + safeSet1.size());System.out.println("safeSet2.size() : " + safeSet2.size());System.out.println("============分隔线============");System.out.println("unsafeList : " + unsafeSet.toString());System.out.println("safeList1 : " + unsafeSet2.toString());System.out.println("safeList2 : " + safeSet1.toString());System.out.println("safeList3 : " + safeSet2.toString());}
}class SetThread implements Runnable {private Set<String> set;public SetThread(Set<String> set) {this.set = set;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {set.add(Thread.currentThread().getName() + String.valueOf(i));try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}
}

输出结果展示:

常用并发数据结构:CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap

Map

  • HashMap:线程不安全
  • HashTable:线程安全,适合写多读少,效率低
  • Collections.synchronizedMap(...):线程安全的,基于synchronized,效率低
  • ConcurrentHashMap:线程安全,非阻塞,适合读多写少,推荐使用;
public class MapDemo {public static void main(String[] args) {// 线程不安全:HashMapMap<String, String> unsafeMap = new HashMap<String, String>();// 线程安全:Hashtable适合写多读少Map<String, String> safeMap1 = new Hashtable<String, String>();// 线程安全:基于synchronized,效率低Map<String, String> safeMap2 = Collections.synchronizedMap(new HashMap<String, String>());// 线程安全:ConcurrentHashMap非阻塞,适合读多写少// 推荐使用Map<String, String> safeMap3 = new ConcurrentHashMap<>();MapThread t1 = new MapThread(unsafeMap);MapThread t2 = new MapThread(safeMap1);MapThread t3 = new MapThread(safeMap2);MapThread t4 = new MapThread(safeMap3);for (int i = 0; i < 10; i++) {new Thread(t1,String.valueOf(i)).start();}for (int i = 0; i < 10; i++) {new Thread(t2,String.valueOf(i)).start();}for (int i = 0; i < 10; i++) {new Thread(t3,String.valueOf(i)).start();}for (int i = 0; i < 10; i++) {new Thread(t4,String.valueOf(i)).start();}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("unsafeMap.size() : " + unsafeMap.size());System.out.println("safeMap1.size() : " + safeMap1.size());System.out.println("safeMap2.size() : " + safeMap2.size());System.out.println("safeMap3.size() : " + safeMap3.size());System.out.println("============分隔线============");System.out.println("unsafeMap : " + unsafeMap.toString());System.out.println("safeMap1 : " + safeMap1.toString());System.out.println("safeMap2 : " + safeMap2.toString());System.out.println("safeMap3 : " + safeMap3.toString());}
}class MapThread implements Runnable {private Map<String,String> map;public MapThread(Map<String,String> map) {this.map = map;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {String kv = Thread.currentThread().getName() + String.valueOf(i);map.put(kv, kv);try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}
}

 

  相关解决方案