并发数据结构:添加或删除
- 阻塞式集合:当集合为空或满时,等待;
- 非阻塞式集合:当集合为空或满时,不等待,返回null或抛出异常!
List
- ArrayList:线程不安全;
- Vector:线程安全,适合写多读少,效率低(几乎所有的读写操作都加了synchronized);
- Collections.synchronizedList(...):线程安全,使用synchronized,效率低;
- CopyOnWriteArrayList:线程安全,非阻塞的,适合读多写少,推荐使用;
public class ListTypeDemo {
public static void main(String[] args) {
// 线程不安全:ArrayList
List<String> unsafeList = new ArrayList<String>();
// 线程安全:Vector适合写多读少,性能差,不推荐使用
List<String> safeList1 = new Vector<String>();
// 线程安全:基于synchronized,效率差,不推荐使用
List<String> safeList2 = Collections.synchronizedList(new ArrayList<String>());
// 线程安全:CopyOnWriteArrayList非阻塞的(当集合为空或满时,返回NULL或抛出异常),适合读多写少
// 推荐使用CopyOnWriteArrayList
List<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;
}
@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<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;
}
@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<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;
}
@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();
}
}
}
}