zoukankan      html  css  js  c++  java
  • 为什么使用ConcurrentHashMap

    ConcurrentHashMap是有Segment数组结构和HashEntry数组结构组成。

    Segment是一种可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色;

    HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组。

    Segment的结构和HashMap类似,是一种数组和链表结构。一个Segment包含一个HashEntry数组,

    每个HashEntry是一个链表结构的元素,每一个Segment守护着一个HashEntry数组里的元素,当对

    HashEntry数组的数据进行修改时,必须首先获得与它对应的Segment锁。

     1 /**
     2      * 
     3      * @Description 
     4      * 1.线程不安全的HashMap
     5      *   HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的
     6      * Entry链表形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,
     7      * 就会产生死循环获取Entry。
     8      * 2.效率低下的HashTable
     9      *   HashTable容器会使用synchronized来保证线程安全,但是在线程竞争激烈的情况下
    10      * HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法,其他线程也访问HashTable
    11      * 的同步方法时,会进入阻塞或轮询状态。如线程1使用put进行元素添加,线程2不但不能使用put方法添加元素,
    12      * 也不能使用get方法来获取元素,所以竞争越激烈效率越低。
    13      * 3.ConcurrentHashMap的分段技术可有效提升并发访问率
    14      *   HashTable容器在竞争激烈的并发环境下表现出效率低下的原因是所有访问HashTable的线程
    15      *   都必须竞争同一把锁,假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程
    16      *   访问容器不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并发访问效率,这就是
    17      *   ConcurrentHashMap所使用的锁分段技术。首先将数据分成一段一段地存储,然后给每一段数据配一把锁,
    18      *   当一个线程占用锁访问其中一个段数据的时候,其他段数据也能被其他线程访问。
    19      * @throws Exception
    20      */
    21     @Test
    22     public void testHashMap() throws Exception {
    23         final HashMap<String, String> map = new HashMap<String, String>(2);
    24         
    25         Thread t = new Thread(new Runnable() {
    26             
    27             @Override
    28             public void run() {
    29                 for(int i=0; i<100000;i++){
    30                     new Thread(new Runnable() {
    31                         
    32                         @Override
    33                         public void run() {
    34                             map.put(UUID.randomUUID().toString(), "");
    35                         }
    36                     }, "ftf"+i).start();
    37                 }
    38                 
    39             }
    40         }, "ftf");
    41         
    42         t.start();
    43         t.join();
    44     }

    来源:《Java并发编程的艺术》

    IT技术和行业交流群 417691667

  • 相关阅读:
    Windows SDK编程(Delphi版) 之 应用基础,楔子
    一个小问题引发的论证思考
    Delphi 组件开发教程指南(7)继续模拟动画显示控件
    用PyInstaller将python转成可执行文件exe笔记
    使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)
    Microsof Office SharePoint 2007 工作流开发环境搭建
    How to monitor Web server performance by using counter logs in System Monitor in IIS
    LINQ之Order By
    window 性能监视器
    内存泄露检测工具
  • 原文地址:https://www.cnblogs.com/sun-rain/p/5719941.html
Copyright © 2011-2022 走看看