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    }