Java 集合类
线程安全与线程不安全
参考链接
https://www.cnblogs.com/williamjie/p/9099141.html
https://www.cnblogs.com/heyonggang/p/9112731.html
https://blog.csdn.net/andy_budd/article/details/81413464
https://blog.csdn.net/wufaliang003/article/details/80219296
https://blog.csdn.net/VIP_WangSai/article/details/70182933
https://blog.csdn.net/qq_41216743/article/details/101311040
https://blog.csdn.net/cn12306com/article/details/81318871
相关面试题
1. 举例说明List 、Set、HashMap是线程不安全的
List
我们知道ArrayList 是线程不安全的,请编写一个不安全的案例并给出解决方案?对于List我们使用的大多数场景是在单线程下,如果在高并发的情况下,便会出现一些线程不安全的问题
1public class ContainerNotSafeDemo {
2 public static void main(String[] args) throws InterruptedException {
3 List<String> list = new ArrayList<>();
4
5// 3种解决方案
6// List<String> list = new Vector<>();
7// List list = Collections.synchronizedList(new ArrayList<>());
8// List list = new CopyOnWriteArrayList();
9
10 for (int i = 0; i < 30; i++) { // 30 个线程,每一个线程都有对list的写与读操作
11 new Thread(() -> {
12 list.add(String.valueOf(new Random().nextInt(100)));
13// System.out.println(list); // 如果没有这一行就不会抛异常,但是list中的数据也不是30个
14 }, String.valueOf(i)).start();
15 }
16
17
18 Thread.sleep(3000);
19 System.out.println(list+""+list.size());
20 }
21}
22
23/*1.故障现象
24* 报错java.util.ConcurrentModificationException
25* 2.导致原因
26* 并发争抢修改导致
27* 3.解决方案
28* new Vector();
29* Collections.synchronizedList(new ArrayList<>());
30* new CopyOnWriteArrayList<>();
31* 4.优化建议
32* 在读多写少的时候推荐使用 CopeOnWriteArrayList 这个类
33*/
CopyOnWriteArrayList
说明:
CopyOnWrite容器即写时复制容器。往一个容器添加元素时,不直接往当前容器Object[] 进行Copy,复制出一个新的容器Object[] newElements, 然后新的容器setArray(newElements); 这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一直读写分离的思想,读和写是不同的容器。
CopyOnWriteArrayList 下的Add方法:
1 public boolean add(E e) {
2 final ReentrantLock lock = this.lock;
3 lock.lock();
4 try {
5 Object[] elements = getArray();
6 int len = elements.length;
7 Object[] newElements = Arrays.copyOf(elements, len + 1);
8 newElements[len] = e;
9 setArray(newElements);
10 return true;
11 } finally {
12 lock.unlock();
13 }
14 }
Set
Set 是线程不安全的,请编写一个不安全的案例并给出解决方案?
1 public static void main(String[] args) {
2 Set<String> set = new HashSet<>(); //导致线程不安全
3// 2种解决方案
4// Set<String> set = Collections.synchronizedSet(new HashSet<>());
5// Set<String> set = new CopyOnWriteArraySet<>();
6 for (int i = 1; i <= 30; i++) {
7 new Thread(()->{
8 set.add(UUID.randomUUID().toString().substring(0,8));
9 System.out.println(set);
10 },String.valueOf(i)).start();
11 }
12 //HashSet 底层是HashMap
13 }
HashMap
HashMap 是线程不安全的,请编写一个不安全的案例并给出解决方案?
1 public static void main(String[] args) {
2 Map<String,String> map = new HashMap<>(); //导致线程不安全
3// 2种解决方案
4// Map<String,String> map = Collections.synchronizedMap(new HashMap<>());
5// Map<String,String> map = new ConcurrentHashMap<>();
6 for (int i = 0; i <= 30; i++) {
7 new Thread(()->{
8 map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,8));
9 System.out.println(map);
10 },String.valueOf(i)).start();
11 }
12 }