java面试-集合类不安全问题及解决方案
2024-08-30 04:43:38
一、List
1、代码演示
public class ArrayListNotSafeDemo { public static void main(String[] args) {
List<String> list = new ArrayList<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
//Constructs an empty list with an initial capacity of ten.
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
2、故障现象
java.util.ConcurrentModificationException
3、导致原因
一个线程正在写,另一线程过来抢夺,导致数据不一致,即并发修改导致的异常
4、解决方案
- new Vector<>()
- Collections.synchronizedList()
- new CopyOnWriteArrayList<>()
在读多写少的时候推荐使用 CopeOnWriteArrayList 这个类
写时复制,读写分离的思想 好处:读操作完全无锁
使用场景 :写操作非常少的场合,能容忍读写的短暂不一致。
CopyOnWriteArrayList迭代器是只读的,不支持增删改。
5、 CopyOnWriteArrayList源码解读:
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
二、Set
1、代码演示:
public class HashSetNotSafeDemo { public static void main(String[] args) {
Set<String> list = new HashSet<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
2、解决方案:
- Collections.synchronizedSet()
- new CopyOnWriteArraySet<>()
3、CopyOnWriteArraySet底层源码:
底层使用CopyOnWriteArrayList
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
4、HashSet底层源码
HashSet的key是你add()的值,value是一个叫PRESENT Object类型的常量,即HashSet只关心key
public HashSet() {
map = new HashMap<>();
} private static final Object PRESENT = new Object(); public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
三、Map
1、代码演示:
public class HashMapNotSafeDemo { public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
System.out.println(map);
}, String.valueOf(i)).start();
}
}
}
2、解决方案
- Collections.synchronizedMap()
- new ConcurrentHashMap<>();
最新文章
- <;![CDATA[]]>;作用
- 一点一滴学shell
- java8新语法
- HDU 1548 A strange lift (Dijkstra)
- JQUERY1.9学习笔记 之基本过滤器(六) 页眉选择器
- iOS https认证 &;&; SSL/TLS证书申请
- Android IT资讯网络阅读器应用源码
- 隐藏快捷方式扩展名(.lnk)
- 201521123122《Java程序设计》第1周学习总结
- DedeCMS实现自定义表单提交后发送指定QQ邮箱法
- 【转载】看StackOverflow如何用25台服务器撑起5.6亿的月PV
- python基础语法-->;多项分支-->;巢状分支
- 如何绘制UML图?
- flask之flask-script组件
- Springboot学习04-默认错误页面加载机制源码分析
- Java操作Kafka
- Java并发编程--BlockingQueue
- tomcat源码阅读之StandardWrapper解析
- NET项目发布到IIS上报错:HTTP 错误 403.14
- PBOC电子现金的交易流程
热门文章
- 比特币大涨之际,VAST空投火爆来袭!
- TypeError: Object of type &#39;datetime&#39; is not JSON serializable
- 几个小实践带你快速上手MindSpore
- Django-1.11中文文档-模型Models(一)
- Newbe.Claptrap 框架入门,第二步 —— 创建项目
- Youcans 的第一篇博客
- MySQL深入研究--学习总结(1)
- java帝国的诞生
- CentOS rpm常用功能记录
- 破解 Android 上 airpods 连接软件的pro版