HashTable 写操作时候,Lock全表 
 
源码:
 public synchronized V put(K key, V value) {
 // Make sure the value is not null
 if (value == null) {
     throw new NullPointerException();
 }
 
 // Makes sure the key is not already in the hashtable.
 Entry tab[] = table;
 int hash = key.hashCode();
 int index = (hash & 0x7FFFFFFF) % tab.length;
 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
  V old = e.value;
  e.value = value;
  return old;
     }
 }
 
因为该方法是用了synchronized方法,因此,可以防止多个线程同时方法这个对象的synchronized方法
对象中 remove,putAll,clear等常用方法都是用了synchronized 方法,因此,当一个线程调用其中的一个synchronized方法时,其他线程就不能方法对象中其中的任何一个synchronized方法。
 

ConcurrentHashMap 允许多个修改操作并发进行
 
ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table。
  /**
     * The segments, each of which is a specialized hash table
     */
    final Segment[] segments;
 
一个ConcurrentHashMap中默认有16个Segment段,源码如下:
/**
     * The default number of concurrency control segments.
     **/
    static final int DEFAULT_SEGMENTS = 16;
 
现在看一下put 方法,源码
 public V put(K key, V value) {
        if (value == null)
            throw new NullPointerException();
        int hash = hash(key);
        return segmentFor(hash).put(key, hash, value, false);
    }
可见方法中不支持value为null的情况,如果为空则抛出空指针异常
操作时通过segmentFor方法得到 Segment[]中的Segment<K,V>,然后将KEY和VALUE存入segment中
再看一下Segment<K,V>对象的put方法
 
 V put(K key, int hash, V value, boolean onlyIfAbsent) {
            lock();  //加锁
            try {
                int c = count;
                if (c++ > threshold) // ensure capacity
                    rehash();
                HashEntry[] tab = table;
                int index = hash & (tab.length - 1);
                HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
                HashEntry<K,V> e = first;
                while (e != null && (e.hash != hash || !key.equals(e.key)))  
                    e = e.next;  //查找到旧值
 
                V oldValue;
                if (e != null) {  //存在修改值
                    oldValue = e.value;
                    if (!onlyIfAbsent)
                        e.value = value;
                }
                else {  //不存在创建新的HashEntry保存数据
                    oldValue = null;
                    ++modCount;
                    tab[index] = new HashEntry<K,V>(key, hash, first, value);
                    count = c; // write-volatile
                }
                return oldValue;
            } finally {
                unlock(); //释放锁
            }
 
结论图:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

【JAVA】ConcurrentHashMap的更多相关文章

  1. 【Java】代处理?代理模式 - 静态代理,动态代理

    >不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算, ...

  2. 【Java】推断文件的后缀名

    这本来不是一个问题,利用框架本来有的方法.或者File类的getPath()方法,取出要推断文件路径.或者getName()方法取出文件路径,成为一个String字符串如果为fileName之后,再对 ...

  3. 【JAVA】【NIO】3、Java NIO Channel

    Java NIO和流量相似,但有些差异: ·通道可读写,流仅支持单向.读或写 ·异步通道读取 ·通道读写器,他们是和Buffer交替 道的实现 下面是Java NIO中最重要的通道的实现: ·File ...

  4. 【JAVA】【NIO】5、Java NIO Scatter / Gather

    标题手段Java NIO该分散体浓缩 Java NIO内置支持分散与收集.的概念主要用于信道分散聚集的读写. 读出的分散体的一个通道被读多个数据buffer在.因此.数据分散到多个buffer中. 对 ...

  5. 【Java】0X001.配置开发环境,JDK、classpath等

    [Java]0x01 配置开发环境,JDK.CLASSPATH等 一. 下载JDK安装文件 首先,进入Oracle官网Java页面. 注意,要下载的是JDK而不是JRE,这点很重要,因为JRE并不包含 ...

  6. for循环输出空心菱形的形状【java】

    使用for循环语句输出以下“空心菱形”效果: * * * * * * * * * * * * * * * * 建议优先参考笔者的另一篇文章:<for循环输出菱形的形状[java]> 代码: ...

  7. 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势

    0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...

  8. 【Java】NO.83.Tool.1.GlassFish.1.001-【GlassFish 5 安装使用】-

    1.0.0 Summary Tittle:[Java]NO.83.Tool.1.GlassFish.1.001-[GlassFish 5 安装使用]- Style:EBook Series:Java ...

  9. 【Java】NO.84.Project.1.OCEA.1.001-【Dreamcar】-

    1.0.0 Summary Tittle:[Java]NO.84.Project.1.OCEA.1.001-[Dreamcar]- Style:Project Series:Java Since:20 ...

随机推荐

  1. Java获取当前时间年月日、时间格式化打印、字符串转日期

    package com.sysc.simple; import java.text.ParseException; import java.text.SimpleDateFormat; import ...

  2. ASP.NET Identity 3.0教程

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:我相信有些人和我一样,已经开始把ASP.NET 5用于产品开发了.不过现在最大的问题是 ...

  3. Codeforces Round #227 (Div. 2) E. George and Cards set内二分+树状数组

    E. George and Cards   George is a cat, so he loves playing very much. Vitaly put n cards in a row in ...

  4. TCP状态转换图详解

    以下对几个关键的中间状态进行说明: 三次握手: LISTEN:表示服务器的某个SOCKET处于监听状态,可以进行连接了. SYN_SENT:表示客户端的某个SOCKET与服务器进行connect时,首 ...

  5. android加载大量图片内存溢出的三种方法

    android加载大量图片内存溢出的三种解决办法 方法一:  在从网络或本地加载图片的时候,只加载缩略图. /** * 按照路径加载图片 * @param path 图片资源的存放路径 * @para ...

  6. flex模拟微信布局

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  7. 【架构】MVP模型

    MVP模型一般要创建三个文件夹:View.Interactor(Model).Presenter 每个部分都有其接口和实现类,就是为了方便回调 这里做一个登陆界面为例子: 接口: Interactor ...

  8. hdu 1251 字典树的应用

    这道题看了大神的模板,直接用字典树提交的会爆内存,用stl 里的map有简单有快 #include <iostream> #include <map> #include < ...

  9. poj1753 bfs+奇偶性减枝//状压搜索

    http://poj.org/problem?id=1753 题意:有个4*4的棋盘,上面摆着黑棋和白旗,b代表黑棋,w代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右) ...

  10. PHP之数据类型

    1.PHP字符串(String):一个字符串是一串字符的序列,就像"Hello world!":可以将任何文本放在单引号和双引号中: <?php $x="Hello ...