java 如何解决获取资源链接不安全的问题_java面试-集合类不安全问题及解决方案...

本文探讨了Java中List、Set和Map在并发环境下的不安全问题,通过故障现象、原因分析,提出了解决方案,包括使用Vector、Collections.synchronizedList、CopyOnWriteArrayList、CopyOnWriteArraySet和ConcurrentHashMap等线程安全的集合类。
摘要由CSDN通过智能技术生成

一、List

1、代码演示

public class ArrayListNotSafeDemo {

public static void main(String[] args) {

List 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 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();

}

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 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<>();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值