并发编程之的HashSet和HashMap的详细解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 并发编程之的HashSet和HashMap的详细解析

HashSet不安全

HashSet也是线程不安全的,底层没有进行任何线程同步处理。

在hashset的源码中,底层是用hashmap实现的:

每次add的时候,把值放在了map对象中的key,而map对象的value则全部统一放一个常量:

在下面的demo中,hashset在多线程情况下和arrayList一样会抛出java.util.ConcurrentModificationException

/**
 * @author zkw
 * @Description HashSet不安全
 */
public class ThreadHashSet {
    public static void main(String[] args) {
        Set<String> list = new HashSet<>();
        for (int i = 0; i < 30; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            }, i+"").start();
        }
    }
}

解决方法 使用 CopyOnWriteArraySet

public class ThreadHashSet {
    public static void main(String[] args) {
        Set<String> list = new CopyOnWriteArraySet<>();
        for (int i = 0; i < 30; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            }, i+"").start();
        }
    }
}

HashMap不安全

使用HashMap空参构造,其初始容量是16,负载因子0.75

初始容量和负载因子都可以自定义,构造方法如下:

HashMap同上面两个类一样,在多线程情况下会出现并发修改异常java.util.ConcurrentModificationException

解决方法:使用ConcurrentHashMap

  public static void main(String[] args) {
        Map<String,String> list = new ConcurrentHashMap<>();
        for (int i = 0; i < 30; i++) {
            new Thread(()->{
                list.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            }, i+"").start();
        }
    }


相关文章
|
14天前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
28 0
|
2天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
13 3
|
12天前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
37 5
|
16天前
|
存储 缓存 Java
HashMap源码解析
HashMap源码解析
|
14天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
34 0
|
14天前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
27 0
|
14天前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
35 0
|
1月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
324 37
|
13天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
13天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)

推荐镜像

更多