JUC之集合

本文探讨了线程不安全的问题,特别是在集合类中的表现,并通过实例展示了ArrayList在多线程环境下的ConcurrentModificationException异常。同时介绍了Java.util.concurrent(JUC)包提供的工具类和集合类来解决这些问题。

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

常见的有哪些是线程不安全的?

1、集合类是不安全的:ArrayList,HashSet,HashMap等等都是不安全

2、i++, ++i 也是不安全

JUC什么?

1、juc是java.util.concurrent包的简称,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的Collection 实现等

2、高并发最容易出现的异常是:

ConcurrentModificationException

3、高并发的项目不能使用ArraryList,只能使用juc报下的集合


 * 1    lambda Express
 *  1.1 如何写:    拷贝形括号,写死右箭头,落地大括号
 *  1.2 Lamdba 有且仅有一个方法,注解@FunctionalInterface
 *  1.3 default
 *  1.4 静态方法

一、题目:请举例说明集合类是不安全的-----面试题

 List<String> list = new ArrayList<String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(1,4));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

运行该代码会报:ConcurrentModificationException异常

为什么会出现这种情况?1.5版本之前是使用的线程安全,但是为了效率改成了不安全的,详情见https://blog.youkuaiyun.com/u012859681/article/details/78206494

二、使用JUC解决

原理:写时复制,这个类似于mysql的读写分离

 CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy, 复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里添加元素,添加完元素之后,
     再将原容器的引用指向新的容器 setArray(newElements);。这样做的好处是可以对CopyOnWrite容器进行并发的读,
     而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器
     public boolean add(E e) {
     final ReentrantLock lock = this.lock;
     lock.lock();
     try {
     Object[] ele ments = getArray();
     int len = elements.length;
     Object[] newElements = Arrays.copyOf(elements, len + 1);
     newElements[len] = e;
     setArray(newElements);
     return true;
     } finally {
     lock.unlock();
        }
     }

实现代码:

list----CopyOnWriteArrayList

set----CopyOnWriteArraySet

map---ConcurrentHashMap

List<String> list = new CopyOnWriteArrayList<String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(1,4));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

 Set<String> set = new CopyOnWriteArraySet<String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(1,4));
                System.out.println(set);
            },String.valueOf(i)).start();
        }

 Map<String,String> map = new ConcurrentHashMap<String,String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(1,4));
                System.out.println(map);
            },String.valueOf(i)).start();

        }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值