目录
一、CopyOnWriteArrayList解决ArrayList不安全
CopyOnWriteArrayList比Vector强在哪里:
二、CopyOnWriteArraySet解决HashSet不安全
三、ConcurrentHashMap解决HashMap不安全
0、警醒自己
1、学习不用心,骗人又骗己;
2、学习不刻苦,纸上画老虎;
3、学习不惜时,终得人耻笑;
4、学习不复习,不如不学习;
5、学习不休息,毁眼伤身体;
7、狗才等着别人喂,狼都是自己寻找食物;
一、CopyOnWriteArrayList解决ArrayList不安全
1、概述
(见代码和注释)
package com.zibo.unsafe;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
//List不安全
public class ListTest {
public static void main(String[] args) {
//单线程下,这个非常安全
// List<String> list = Arrays.asList("1", "2", "3");
// list.forEach(System.out::println);
//多线程测试
//看起来没什么问题,但是报错了ConcurrentModificationException 并发修改异常
// synchronized Vector出现于JDK1.0,是加了synchronized的,ArrayList出现于JDK1.2,没有加synchronized
/*
* 解决方案:
* 1、使用List<String> list = new Vector<>();,这个答案对,但是一个很愚蠢的答案;
* 2、让ArrayList变得安全:List<String> list = Collections.synchronizedList(new ArrayList<>());
* 3、JUC的解决方案:List<String> list = new CopyOnWriteArrayList<>();
*/
//CopyOnWrite,写入时复制,COW,计算机程序设计领域的一种优化策略
//多个线程调用的时候,list,读取的时候,固定的,写入(覆盖)
//在写入的时候避免覆盖造成数据问题
//c比Vector强在哪里?
//Vector的add方法加了synchronized,执行效率低;
//CopyOnWriteArrayList的add方法用的是lock锁
//(数据库)读写分离 MyCat
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
2、总结
解决ArrayList多线程不安全的三种方案:
* 1、使用List<String> list = new Vector<>();,这个答案对,但是一个很笨拙的答案;
* 2、让ArrayList变得安全:List<String> list = Collections.synchronizedList(new ArrayList<>());
* 3、JUC的解决方案:List<String> list = new CopyOnWriteArrayList<>();
CopyOnWriteArrayList比Vector强在哪里:
Vector的add方法加了synchronized,执行效率低;CopyOnWriteArrayList的add方法用的是lock锁;
二、CopyOnWriteArraySet解决HashSet不安全
1、代码及注释
package com.zibo.unsafe;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
//Set不安全
public class SetTest {
public static void main(String[] args) {
// Set<String> set = new HashSet<>();
//ConcurrentModificationException并发修改异常
/*
* 解决方案:
* 1、Set<String> set = Collections.synchronizedSet(new HashSet<>());
* 2、Set<String> set = new CopyOnWriteArraySet<>();
*/
//解决方案1
// Set<String> set = Collections.synchronizedSet(new HashSet<>());
//解决方案2
Set<String> set = new CopyOnWriteArraySet<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
},String.valueOf(i)).start();
}
}
}
2、总结
解决HashSet不安全的两种解决方案:
* 1、Set<String> set = Collections.synchronizedSet(new HashSet<>());
* 2、Set<String> set = new CopyOnWriteArraySet<>();
3、HashSet底层是什么
底层是HashMap:
HashSet的add方法:
使用HashMap的key不重复的特性实现HashSet;
三、ConcurrentHashMap解决HashMap不安全
1、代码及注释
package com.zibo.unsafe;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
//Map不安全
public class TestMap {
public static void main(String[] args) {
// Map<String, String> map = new HashMap<>();
// 首先map是这样用的吗?工作中不用HashMap
// 默认等价于什么?Map<String, String> map = new HashMap<>(16,0.75);loadFactor加载因子0.75,初始容量16
//ConcurrentModificationException集合修改异常
/*
* 解决方案:
* 1、Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
* 2、Map<String, String> map = new ConcurrentHashMap<>();
*/
//解决方案1
// Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
//解决方案2
Map<String, String> map = new ConcurrentHashMap<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
System.out.println(map);
},String.valueOf(i)).start();
}
}
}
2、解决HashMap不安全的两种方案
* 1、Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
* 2、Map<String, String> map = new ConcurrentHashMap<>();
3、HashMap的默认实现