集合类不安全_List_Set_HashMap
Posted 偶像java练习生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合类不安全_List_Set_HashMap相关的知识,希望对你有一定的参考价值。
集合类不安全
1.单线程的代码永远是安全的
并发下这些所有的集合类都有问题
List 不安全
代码案例:
package com.unsafe;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 面试官问写代码遇到什么异常?
* 可以回答的高级点
* 1.我遇到的是OOM 内存异常
* 2.我遇到java.util.ConcurrentModificationException 并发修改异常!
*
*1.解决ArrayList 不安全方案
*
*/
public class ListTest {
public static void main(String[] args) {
// List<String> list = Arrays.asList("1", "2", "3");
// list.forEach(System.out::println);
//并发下ArrayList 不安全吗? 不安全
/**
* 解决方案:
* 1. list 下面还有一个Vector 默认就是安全的
* 2. List<String> list = Collections.synchronizedList(new ArrayList<>());
* 3. List<String> list = new CopyOnWriteArrayList<>();
*/
//ArrayList<String> list = new ArrayList<>();
//List<String> list = new Vector<>();
//将一个ArrayList 变得安全
//List<String> list = Collections.synchronizedList(new ArrayList<>());
//CopyOnWrite 写入时复制 COW 计算机程序设计领域的一种优化策略
//多个线程调用的时候,list,读取的时候,固定的,写入的时候存在覆盖操作,写入(覆盖)
// 在写入的时候避免覆盖,造成数据问题!
// 读写分离 Mycat
// 为什么不用Vector 而用 copyOnWriteArrayList?
//Vector 用的是synchronized 效率比较低,而CopyOnWriteArrayList 用的是lock 锁
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();
}
}
}
小狂神的学习方法推荐: 1.先会用,2,货比3家,寻找其他解决方案,3 ,分析源码
Vector 用关键字synchronized 关键字修饰,是线程安全的
CopyOnWriteArrayList :写入时复制
lock 锁
- 先初始化一个数组,
- 获取之前数组长度,
- 复制之前的数组并且长度加1
- 将add 的新增到对应数组的位置
- 将数组转化为List
Set 不安全
Collection 下面还有一个叫阻塞队列的东西BlockingQueue
package com.unsafe;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* 同理可证: ConcurrentModificationException 并发修改异常
* // 工具类写法:1..通过集合类使用synchronizedSet 方法 Set<Object> objects = Collections.synchronizedSet(new HashSet<>());
* // JUC 写法: Set<String> set = new CopyOnWriteArraySet<>(); 写入时复制
*/
public class SetTest {
public static void main(String[] args) {
// Set<String> set = new HashSet<>();
//如何将set 变成线程安全的
//1.通过结合类使用synchronizedSet 方法
//
// Set<Object> objects = Collections.synchronizedSet(new HashSet<>());
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();
}
}
}
HashSet 底层是什么?
HashSet 的底层就是HashMap
//add 方法本质方法是map 的key 是无法重复的!而put 里面的Value Present 是不变的值
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
//PRESENT 是常量
private static final Object PRESENT = new Object();//不变的值
Map 不安全
回顾hashMap 的基本操作
1.理解这些是什么
package com.unsafe;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* java.util.ConcurrentModificationException 并发修改异常
* 如何将hashMap 编程线程安全的?
* 1.使用工具类Collections.SynchronizedMap
* 2.使用类ConcurrentHashMap
*
*/
public class MapTest {
public static void main(String[] args) {
//map 是这样用的吗? 不是,工作中不用HashMap
// 默认等价于什么?
//Map<String, String> hashMap = new HashMap(16,0.75f);
//加载因子,初始化容量
// Map<String, String> map = new HashMap();
//如何变成线程安全的
// 1.使用工具类Collections :Map<Object, Object> objectObjectMap = Collections.synchronizedMap(new HashMap());
// 2.使用ConcurrentHashMap 类 线程安全的
//研究一下ConcurrentHashMap 原理????
Map<String,String> 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();
}
}
}
以上是关于集合类不安全_List_Set_HashMap的主要内容,如果未能解决你的问题,请参考以下文章