文章目录
  1. ConcurrentHashMap源码分析
  2. 1 为什么采用ConcurrentHashMap
    1. 1.1 HashMap的问题
    2. 1.2 HashTable的问题
  3. 2. ConcurrentHashMap简介

[TOC]

ConcurrentHashMap源码分析

熟悉了HashMap和HashTable,下面就来聊一聊并发问题。。以及说一说 ConcurrentHashMap的分析。

1 为什么采用ConcurrentHashMap

为什么在多线程的环境下java建议使用ConcurrentHashMap呢,那么首先从HashMap和HashTable的缺点出发。

1.1 HashMap的问题

首先大家大家都知道HashMap是线程不安全的,那为毛不安全呢。。
不安全总的来说就出在HashMap的扩容问题上,当多个线程同时进行对扩容进行的操作的时候,那么就会引发安全的问题。该问题就会导致每个存储数据的某个链表形成环路。这样在get操作的时候,就会导致死循环。

参考:《疫苗:Java HashMap的死循环》 http://coolshell.cn/articles/9606.html

1.2 HashTable的问题

HashTable中的方法都是用了synchronized关键字来保证线程安全,但是在多线程的环境下,HashTable的效率就显得十分低下。当一个线程在进行put操作的时候,其他的线程在访问HashTable的时候都必须进入阻塞状态,等待该线程方法完成。甚至最糟糕的是,当一个线程在put操作的时候,其他线程都不能进行get操作,所以多线程下效率十分低下。

2. ConcurrentHashMap简介

由于HashMap和HashTable存在诸多问题,所以在多线程的环境最好采用ConcurrentHashMap。下面是ConcurrentHashMap的内部结构图。

从图中可以看出ConcurrentHashMap将原来的整个Hash表又拆分成若干个部分,分别放到segments数组中。这个就需要进行二次散列进行存放数据,首先对key进行hash运算找到对应的segment,然后在进行一个hash运算找到对应的桶,最后进行获取或者存入操作。
那他怎么进行线程安全操作的呢?就像这样由于存在多个segments,然后对每个segment分别进行lock和unlock的操作,譬如线程1访问的是segment1,线程2访问的是segment2,那么这两个在操作数据的时候不会发生同步阻塞的问题,这样就能够提高并发访问的效率问题。
你也可以很粗糙的认为 ConcurrentHashMap将一个大的HashTable拆分成了若干个小的HashTable。

关于更详细一点的参照:
《ConcurrentHashmap 解析》 http://my.oschina.net/zhenglingfei/blog/400515?fromerr=MfsX1eNM
《深入分析ConcurrentHashMap》 http://ifeve.com/concurrenthashmap/

文章目录
  1. ConcurrentHashMap源码分析
  2. 1 为什么采用ConcurrentHashMap
    1. 1.1 HashMap的问题
    2. 1.2 HashTable的问题
  3. 2. ConcurrentHashMap简介