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

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

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

List

  • ArrayList:线程不安全;
  • Vector:线程安全,适合写多读少,效率低(几乎所有的读写操作都加了synchronized);
  • Collections.synchronizedList(...):线程安全,使用synchronized,效率低;
  • CopyOnWriteArrayList:线程安全,非阻塞的,适合读多写少,推荐使用;
public class ListTypeDemo {

	public static void main(String[] args) {
		// 线程不安全:ArrayList
		List unsafeList = new ArrayList();
		// 线程安全:Vector适合写多读少,性能差,不推荐使用
		List safeList1 = new Vector();
		// 线程安全:基于synchronized,效率差,不推荐使用
		List safeList2 = Collections.synchronizedList(new ArrayList());
		// 线程安全:CopyOnWriteArrayList非阻塞的(当集合为空或满时,返回NULL或抛出异常),适合读多写少
		// 推荐使用CopyOnWriteArrayList
		List safeList3 = new CopyOnWriteArrayList();
		
		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 list;

	public ListThread(List list) {
		this.list = list;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			list.add(String.valueOf(i));
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

输出结果展示:

Set

  • HashSet:线程不安全;
  • Collections.synchronizedSet(...):线程安全,使用synchronized,效率低;
  • CopyOnWriteArraySet:线程安全,非阻塞,适合读多写少,推荐使用;
public class SetTypeDemo {

	public static void main(String[] args) {
		// 线程不安全:HashSet
		Set unsafeSet = new HashSet();
		// 线程不安全:TreeSet,对Set集合中的元素进行排序,是线程不安全的
		Set unsafeSet2 = new TreeSet();
		// 线程安全:
		Set safeSet1 = Collections.synchronizedSet(new HashSet());
		// 线程安全:CopyOnWriteArraySet,非阻塞,适合读多写少
		// 推荐使用
		Set safeSet2 = new CopyOnWriteArraySet();
		
		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 set;

	public SetThread(Set set) {
		this.set = set;
	}

	@Override
	public 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();
			}
		}
	}
}

输出结果展示:

Map

  • HashMap:线程不安全
  • HashTable:线程安全,适合写多读少,效率低
  • Collections.synchronizedMap(...):线程安全的,基于synchronized,效率低
  • ConcurrentHashMap:线程安全,非阻塞,适合读多写少,推荐使用;
public class MapDemo {

	public static void main(String[] args) {
		// 线程不安全:HashMap
		Map unsafeMap = new HashMap();
		// 线程安全:Hashtable适合写多读少
		Map safeMap1 = new Hashtable();
		// 线程安全:基于synchronized,效率低
		Map safeMap2 = Collections.synchronizedMap(new HashMap());
		// 线程安全:ConcurrentHashMap非阻塞,适合读多写少
		// 推荐使用
		Map 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 map;

	public MapThread(Map map) {
		this.map = map;
	}

	@Override
	public 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();
			}
		}
	}
}

 

你可能感兴趣的:(java)