Java多线程之集合类(线程安全和不安全)

本文探讨了Java中线程安全与不安全的集合类,包括ArrayList、HashSet、HashMap的线程不安全性,以及CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentHashMap的解决方案。通过对比测试和源码解析,阐述了CopyOnWrite容器如何实现线程安全,并介绍了其读写分离的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java多线程之集合类(浅析线程安全和不安全)


本文目录:

  • 1.线程不安全之ArrayListHashSetHashMap和线程安全之CopyOnWriteArrayListCopyOnWriteArraySetConcurrentHashMap
  • 2. 小结
  • 3.解析CopyOnWrite容器

1.线程不安全之ArrayList和线程安全之CopyOnWriteArrayList


测试代码:

  • 多个线程往一个集合中添加内容。
实现:
public static void listNotSafe() {
        List<String> list = new ArrayList<>();
        for (int i = 1; i <= 30 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,6));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

编译结果:
在这里插入图片描述


解决办法:
  • 使用CopyOnWriteArrayList代替ArrayList

使用如下:

public static void listNotSafe() {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 1; i <= 30 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,6));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

编译结果:
在这里插入图片描述


小结:

  • 1. 经过测试,发现HashSetHashMap也是线程不安全的,分别对应的解决办法是用CopyOnWriteArraySetConcurrentHashMap替换(如上面的例子)

3.解析CopyOnWrite容器

  • 我们发现CopyOnWrite容器能够解决线程不安全的问题,现在来通过源码进行解析(以CopyOnWriteArrayList)为例。

源码部分如下
在这里插入图片描述


其中的add(E e)方法
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();
		    }
		}

可以知道:
  1. 都是有线程锁的,所以是线程安全的
  2. CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[ ]添加,而是先将当前容器Object[ ]进行Copy,复制出一个新的容器Object[] newElements,然后往新的容器Object[ ] newElements里添加元素,添加完元素之后,再将原容器的引用指向新的容器 setArray(newElements)。
  3. 好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器

扩展小知识:
  1. HashSet底层是HashMap
    在这里插入图片描述

  1. 你可能会想,HashSet是一个参数,而HashMap是键值对存在的。那是因为HashSet只用了HashMap是键,它的值是一个固定的Object对象。
    在这里插入图片描述
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值