JUC高并发编程(06) -- 集合的线程安全 -- HashSet集合和HashMap集合

本文探讨了在Java并发环境中,HashSet和HashMap的线程不安全问题,通过案例展示了并发修改异常的原因。解决方案包括使用CopyOnWriteArraySet解决HashSet的安全问题,以及采用ConcurrentHashMap来确保HashMap的线程安全。文章详细解析了相关源码,解释了为何这两个集合在多线程环境下会导致异常,并提供了相应的线程安全实现。
摘要由CSDN通过智能技术生成

JUC高并发编程

五、集合的线程安全

5.2)HashSet集合线程

5.2.1)HashSet集合线程不安全案例展示

代码如下:

// HashSet集合线程不安全案例展示
public class HashSetErrorDemo {
    public static void main(String[] args) {
        //演示Hashset
        Set<String> set = new HashSet<>();
        
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                //向集合添加内容
                set.add(UUID.randomUUID().toString().substring(0, 8));
                //从集合获取内容
                System.out.println(set);
            }, String.valueOf(i)).start();
        }
    }
}

输出:

java.util.ConcurrentModificationException at java.util.HashMapKeyIterator.next(HashMap.java:1469) at java.util.AbstractCollection.toString(AbstractCollection.java:461) at java.lang.String.valueOf(String.java:2994) at java.io.PrintStream.println(PrintStream.java:821) at com.study.collection.HashSetErrorDemo.lambda0(HashSetErrorDemo.java:25) at java.lang.Thread.run(Thread.java:748) java.util.ConcurrentModificationException at java.util.HashMapKeyIterator.next(HashMap.java:1469) at java.util.AbstractCollection.toString(AbstractCollection.java:461) at java.lang.String.valueOf(String.java:2994) at java.io.PrintStream.println(PrintStream.java:821) at com.study.collection.HashSetErrorDemo.lambda0(HashSetErrorDemo.java:25) at java.lang.Thread.run(Thread.java:748)

发现报错,java.util.ConcurrentModificationException ——》并发修改异常

问题: 为什么会出现并发修改异常?

查看HashSet的add方法源码 ,如下:

 /**
     * Adds the specified element to this set if it is not already present.
     * More formally, adds the specified element <tt>e</tt> to this set if
     * this set contains no element <tt>e2</tt> such that
     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
     * If this set already contains the element, the call leaves the set
     * unchanged and returns <tt>false</tt>.
     *
     * @param e element to be added to this set
     * @return <tt>true</tt> if this set did not already contain the specified
     * element
     */
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

add() 方法没有添加 synchronized 关键字,即没有对多线程情况进行处理

5.2.2)HashSet集合线程不安全解决方案

5.2.2.1)解决方案-CopyOnWriteArraySet

使用 CopyOnWriteArraySet解决HashSet集合线程不安全问题,代码如下:

// CopyOnWriteArray解决HashSet集合线程不安全问题
public class CopyOnWriteArraySetDemo {
    public static void main(String[] args) {
        //演示Hashset
        Set<String> set =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值