? ? ArrayList是非線程安全的,而Vector是線程安全的,其實(shí)現(xiàn)依靠synchronized,效率低。雖然能實(shí)現(xiàn)線程安全,但是不符合高并發(fā)。
? ? 因此有ConcurrentHashMap、CopyOnWriteArraySet寫時(shí)復(fù)制技術(shù)CopyOnWriteArrayList這幾個(gè)集合框架。這里需要理解一個(gè)技術(shù):寫時(shí)復(fù)制技術(shù)。
? ? 為了保證線程安全,又要高并發(fā),所以要并發(fā)讀,獨(dú)占寫。舉個(gè)例子,有一個(gè)集合A,有好多人在讀,但是小李想寫數(shù)據(jù),因此小李先根據(jù)集合A復(fù)制一個(gè)集合B,然后把數(shù)據(jù)寫到集合B,最后,把指向集合A的引用,指向集合B。
代碼:
public class NotSafeDemo {
public static void main(String[] args) {
????//notSafeHashSet
????//noSafeArrayList
? ? ?notSafeHashMap();
}
private static void notSafeHashMap() {
????Map map =new ConcurrentHashMap<>();
????for (int i =0; i <30; i++) {
????????new Thread(() -> {
????????map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,4));
????????System.out.println(map);
????????}, String.valueOf(i)).start();
????}
}
private static void notSafeHashSet() {
????Set hashSet =new CopyOnWriteArraySet();
????for (int i =0; i <30; i++) {
????new Thread(() -> {
????????hashSet.add(UUID.randomUUID().toString().substring(0,4));
????????System.out.println(hashSet);
????}, String.valueOf(i)).start();
????}
}
private static void noSafeArrayList() {
List list =new CopyOnWriteArrayList();//寫時(shí)復(fù)制技術(shù)
//并發(fā)寫,會(huì)報(bào)錯(cuò):java.util.ConcurrentModificationException
? ?for (int i =0; i <30; i++) {
????new Thread(() -> {
????????list.add(UUID.randomUUID().toString().substring(0,4));
????????System.out.println(list);
????}, String.valueOf(i)).start();
}
}
}