ArrayList是非线程安全的,而Vector是线程安全的,其实现依靠synchronized,效率低。虽然能实现线程安全,但是不符合高并发。
因此有ConcurrentHashMap、CopyOnWriteArraySet写时复制技术CopyOnWriteArrayList这几个集合框架。这里需要理解一个技术:写时复制技术。
为了保证线程安全,又要高并发,所以要并发读,独占写。举个例子,有一个集合A,有好多人在读,但是小李想写数据,因此小李先根据集合A复制一个集合B,然后把数据写到集合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();//写时复制技术
//并发写,会报错: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();
}
}
}