zoukankan      html  css  js  c++  java
  • ConcurrentHashMap

    ConcurrentHashMap中的key和value值都不能为null,HashMap中key可以为null,HashTable中key不能为null。
    并发编程中ConcurrentHashMap是一个常用的数据结构,在线程安全的基础上提供了更好的写并发能力,是线程安全的类并不能保证使用了ConcurrentHashMap的操作都是线程安全的,大量的利用了volatile,final,CAS等lock-free技术来减少锁竞争对于性能的影响
    使用分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,
    其他段的数据也能被其他线程访问,每个Segment段(继承ReentrantLock),能够实现真正的并发访问

    ConcurrentHashMap中主要实体类就是三个:ConcurrentHashMap(整个Hash表),Segment(桶),HashEntry(节点)


    put方法的线程会获得锁,只有当此线程的put方法执行结束后才会释放锁,获得锁的线程会通知其他试图操作put方法的线程,并通知其他线程出于等待状态,直到释放锁后,其他线程才会去重新竞争锁。保证了ConcurrentHashMap的线程安全

    get方法无需加锁,由于其中涉及到的共享变量都使用volatile修饰,volatile可以保证内存可见性,所以不会读取到过期数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。HashEntry代表每个hash链中的一个节点,其结构如下所示:

    static final class HashEntry<K,V> {

             final K key;  final int hash;   

             volatile V value;  volatile HashEntry<K,V> next;

    }

    总结:
    ConcurrentHashMap使用了线程锁分段技术,每次访问只允许一个线程修改哈希表的映射关系,所以是线程安全的

    ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组Segment继承了ReentrantLock,所以它就是一种可重入锁(ReentrantLock)。在ConcurrentHashMap,一个Segment就是一个子哈希表,Segment里维护了一个HashEntry数组,并发环境下,对于不同Segment的数据进行操作是不用考虑锁竞争的。(理论上就允许16个线程并发执行) 

    Segment类似于HashMap,一个Segment维护着一个HashEntry数组
    如果用户不指定则会使用默认值,initialCapacity为16,loadFactor为0.75(负载因子,扩容时需要参考),concurrentLevel为
    16

    可以使用CocurrentHashMap来代替Hashtable吗?
    这是一个很热门的面试题,因为ConcurrentHashMap越来越多人用了。Hashtable是synchronized的,但是ConcurrentHashMap同步性能更好,因为它仅仅根据同步级别对map的一部分进行上锁。ConcurrentHashMap当然可以代替HashTable,但是HashTable提供更强的线程安全性
    群交流(262200309)
  • 相关阅读:
    Blazor 服务端组件 Render, RenderFragment ,RenderTreeBuilder, CascadingValue/CascadingParameter
    Git Submodule管理项目子模块
    使用Try.NET创建可交互.NET文档
    开包即食的教程带你浅尝最新开源的C# Web引擎 Blazor
    搞懂Xamarin.Forms布局,看这篇应该就够了吧
    【译】.NET 跨平台界面框架和为什么你首先要考虑再三
    Roslyn 语法树中的各种语法节点及每个节点的含义
    数组的子集
    查找字符串中的最长无重复字符的子串
    双通道无限蓝屏
  • 原文地址:https://www.cnblogs.com/webster1/p/8439372.html
Copyright © 2011-2022 走看看