4.1集合不安全的问题
在讲解线程安全的之前,先看线程不安全的 实例
创建 ArrayList集合 并使用线程 再集合中添加元素获取元素
//创建ArrayList集合
List<String> list = new ArrayList<>();
for (int i = 0; i <30; i++) {
new Thread(()->{
//向集合添加内容
list.add(UUID.randomUUID().toString().substring(0,8));
//从集合获取内容
System.out.println(list);
},String.valueOf(i)).start();
}
因为在底层的集合实现,并没有加锁(减少效率) 所以会出现线程异常的问题
那么我们怎么解决呢?(三种方式)
4.1 Vector 4.2 Collections 4.3 CopyOnWriteArrayList(比较常用)
在他们的底层实现,是线程安全的,源代码为
public synchronized boolean add(E e) {
modCount++;
add(e, elementData, elementCount);
return true;
}
所以只需要把集合创建改为下面的三个即可
CopyOnWriteArrayList涉及的底层原理为写时复制技术
- 读的时候并发(多个线程操作)
- 写的时候独立,先复制相同的空间到某个区域,将其写到新区域,旧新合并,并且读新区域(每次加新内容都写到新区域,覆盖合并之前旧区域,读取新区域添加的内容)
4.5 ConcurrentHashMap
将其代码修改为
List<String> list = new CopyOnWriteArrayList<>();