不安全举例
以LinkedList为例,运行一下代码
public static void main(String[] args) {
List<String> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list.toString());//在添加的时候,取值这时候就会发生并发修改的问题
},i+"").start();
}
}结果,可能会正常执行,基本都会报并发修改异常

解决方法
1、Vector(古老效率低)
public static void main(String[] args) {
/*List<String> list = new LinkedList<>();*/
List<String> list = new Vector<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list.toString());
},i+"").start();
}
}这时候运行正常

从源码中可以看到

其方法都是加了synchronize锁的,以此保证线程安全,这样也带来的效率低下的问题
2、利用Collections(同样古老)
public static void main(String[] args) {
/*List<String> list = new LinkedList<>();*/
List<String> list = Collections.synchronizedList(new LinkedList<>());
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(Thread.currentThread().getName()+ ":"+ list.toString());
},i+"").start();
}
}运行结果

3、CopyOnWriteArrayList(写时复制)
public static void main(String[] args) {
/*List<String> list = new LinkedList<>();*/
/*List<String> list = new Vector<>();*/
/*List<String> list = Collections.synchronizedList(new LinkedList<>());*/
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(Thread.currentThread().getName()+ ":"+ list.toString());
},i+"").start();
}
}其原理图

HashMap 和HashSet也同样拥有一样的问题
这时候我们分别用ConcurrentHashMap和CopyOnWriteArraySet就能解决问题。
Map<String,String> map = new ConcurrentHashMap<>();
Set<String> set = new CopyOnWriteArraySet<>();版权声明:本文为weixin_56289362原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。