1、List不安全
CopyOnWriteArrayList
- Arrarlist测试(单线程)
public class ListTest01 {
public static void main(String[] args) {
List<String> list = Arrays.asList("1", "2", "3");
list.forEach(System.out::println);
}
}
- 多线程下ArrayList还安全吗?
- 现在我们创建10个线程来向List添加元素
public class ListTest01 {
public static void main(String[] args) {
//并发下ArrayList不安全
ArrayList<String> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
//UUID(Universally Unique Identifier):
//通用唯一识别码,是一种软件建构的标准.UUID是指在一台机器上生成的数字,
//它保证对在同一时空中的所有机器都是唯一的
//String.valueOf(i),给10个线程分别取名字
}
}
}
解决办法:
1.List list = new Vector<>(); //vector默认是安全的(是同步方法)
2.List list = Collections.synchronizedList(new ArrayList<>());//使用工具类
3.List list = new CopyOnWriteArrayList<>();
CopyOnWrite:写入时复制,COW 计算机程序设计领域的优化策略。
多个线程调用的时候,list是唯一的,读取时固定,写入的时候会先复制一份出来,然后在复制的里面进行写入,然后再赋值回去
CopyOnWriteArrayList 比 Vector 好,
Vector这个用的是Sychronized,效率比CopyOnWriteArrayList低。(有Synchronized修饰的方法,效率都比较低)
2、Set不安全
public class SetTest {
public static void main(String[] args) {
// Set<String> set = new HashSet<>(); //ConcurrentModificationException
// Set<String> set = Collections.synchronizedSet(new HashSet<>());
Set<String> set = new CopyOnWriteArraySet<>();
for (int i = 1; i <= 30; i++) {
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
},String.valueOf(i)).start();
}
}
}
解决办法
Set set = new CopyOnWriteArraySet<>();Set set = Collections.synchronizedSet(new HashSet<>());
hashSet底层是什么
底层是HashMap,set的add的方法本质就是map key,是无法重复的。
3、Map不安全
public class MapTest {
public static void main(String[] args) {
// HashMap<Object, Object> map = new HashMap<>(); //ConcurrentModificationException
// HashMap<Object, Object> map = (HashMap<Object, Object>) Collections.synchronizedMap(new HashMap<>());
Map<Object, Object> map = new ConcurrentHashMap<>();
for (int i = 0; i < 30; i++) {
new Thread(()->{
map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));
System.out.println(map);
},String.valueOf(i)).start();
}
}
}
解决办法HashMap<Object, Object> map =
(HashMap<Object, Object>) Collections.synchronizedMap(new HashMap<>());
Map<Object, Object> map = new ConcurrentHashMap<>();
3.1、扩展
问题:map默认等价于什么
其中16是初始容量,0.75是加载因子