一、概述

ConcurrentHashMap是Java5中新增加的一个线程安全的Map集合,可以用来替代HashTable。

锁分段技术

原理:将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

理解Java存储模型(JMM)的Happens-Before规则

一个例子


public class Test1 {
private int a=1, b=2; public void foo(){ // 线程1
a=3;
b=4;
} public int getA(){ // 线程2
return a;
}
public int getB(){ // 线程2
return b;
}
}

当线程1执行foo方法的时候,线程2访问getA和getB会得到什么样的结果?

A:a=1, b=2  // 都未改变
B:a=3, b=4 // 都改变了
C:a=3, b=2 // a改变了,b未改变
D:a=1, b=4 // b改变了,a未改变

多线程之间内存可见性(Visibility)顺序不一致的问题。有两种可能会造成上面的D选项。

  • Java编译器的重排序
  • 假设代码有两条语句,代码顺序是语句1先于语句2执行;那么只要语句2不依赖于语句1的结果,打乱它们的顺序对最终的结果没有影响的话,那么真正交给CPU去执行时,他们的顺序可以是没有限制的。可以允许语句2先于语句1被CPU执行,和代码中的顺序不一致。
  • 从线程工作内存写回主存时顺序无法保证

JMM中一个重要问题就是:如何让多线程之间,对象的状态对于各线程的“可视性”是顺序一致的。它的解决方式就是 Happens-before 规则:

JMM为所有程序内部动作定义了一个偏序关系,叫做happens-before。要想保证执行动作B的线程看到动作A的结果(无论A和B是否发生在同一个线程中),A和B之间就必须满足happens-before关系。

后续分析ConcurrenHashMap时也会看到使用到锁(ReentrantLock),Volatile,final等手段来保证happens-before规则的。

使用锁方式实现“Happens-before”是最简单,容易理解的。

二、源码


public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable { static class Segment<K,V> extends ReentrantLock implements Serializable {
private static final long serialVersionUID = 2249069246763182397L;
final float loadFactor;
Segment(float lf) { this.loadFactor = lf; }
} }

JDK源码分析(四)—— ConcurrentHashMap的更多相关文章

  1. JDK源码分析(四)——LinkedHashMap

    目录 LinkedHashMap概述 内部字段及构造方法 存储元素 取出元素 删除元素 迭代器 利用LinkedHashMap简单实现LRU算法 总结 LinkedHashMap概述   JDK对Li ...

  2. JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue

    JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue 目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlocki ...

  3. 【JDK】JDK源码分析-TreeMap(2)

    前文「JDK源码分析-TreeMap(1)」分析了 TreeMap 的一些方法,本文分析其中的增删方法.这也是红黑树插入和删除节点的操作,由于相对复杂,因此单独进行分析. 插入操作 该操作其实就是红黑 ...

  4. 【JDK】JDK源码分析-Vector

    概述 上文「JDK源码分析-ArrayList」主要分析了 ArrayList 的实现原理.本文分析 List 接口的另一个实现类:Vector. Vector 的内部实现与 ArrayList 类似 ...

  5. 【JDK】JDK源码分析-AbstractQueuedSynchronizer(2)

    概述 前文「JDK源码分析-AbstractQueuedSynchronizer(1)」初步分析了 AQS,其中提到了 Node 节点的「独占模式」和「共享模式」,其实 AQS 也主要是围绕对这两种模 ...

  6. 【JDK】JDK源码分析-HashMap(2)

    前文「JDK源码分析-HashMap(1)」分析了 HashMap 的内部结构和主要方法的实现原理.但是,面试中通常还会问到很多其他的问题,本文简要分析下常见的一些问题. 这里再贴一下 HashMap ...

  7. JDK 源码分析(4)—— HashMap/LinkedHashMap/Hashtable

    JDK 源码分析(4)-- HashMap/LinkedHashMap/Hashtable HashMap HashMap采用的是哈希算法+链表冲突解决,table的大小永远为2次幂,因为在初始化的时 ...

  8. JDK源码分析(三)—— LinkedList

    参考文档 JDK源码分析(4)之 LinkedList 相关

  9. JDK源码分析(一)—— String

    dir 参考文档 JDK源码分析(1)之 String 相关

  10. JDK源码分析(2)LinkedList

    JDK版本 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作. LinkedList 实现 ...

随机推荐

  1. 远程dump导出svn项目

    使用TortoiseSVN 安装目录下的svnrdump.exe 工具进行导出 1.cmd 到工具路径下 C:\Program Files\TortoiseSVN\bin svnrdump.exe d ...

  2. pyhton中常用的基础模块

    目前在看Google的DetectionAPI源码,自己的Python功底不是很好,看到了哪些模块就随手记一下. 1.abc模块,参考https://www.cnblogs.com/wancy86/p ...

  3. [LeetCode] Transpose Matrix 转置矩阵

    Given a matrix A, return the transpose of A. The transpose of a matrix is the matrix flipped over it ...

  4. oracle中文乱码问题解决

    中文乱码问题解决:1.查看服务器端编码select userenv('language') from dual;我实际查到的结果为:AMERICAN_AMERICA.ZHS16GBK2.执行语句 se ...

  5. laravel 邮件配置

    .env的配置 MAIL_DRIVER=smtpMAIL_HOST=smtp.163.comMAIL_PORT=465MAIL_USERNAME=你的163邮箱地址MAIL_PASSWORD=你的16 ...

  6. Egg 中 Controller 最佳实践

    得益于 JavaScript 加入的 decorator 特性,可以使我们跟 Java/C# 一样,更加直观自然的,做面向切面编程.而随着 TypeScript 的成熟,类型系统也让我们增强了信心,面 ...

  7. Java面试题中常考的容易混淆的知识点区别

    以下是我收集的Java编程里各种区别,供Java学习爱好者参考,这些区别都是每次Java面试中常考的,大家好好掌握,如有失误请留言指出.想要获取Java详细全套学习资料请到上海尚学堂官网获取. 1.H ...

  8. java前后分离使用fetch上传文件失败500

    这次不是写什么技术要点,仅仅是记录一下 最近遇到的一个问题 背景 使用fetch向java后台上传文件时,前端调试报错500,后端的报错为multipart 无法解析,翻译过来大概是这个意思. 由于本 ...

  9. [Swift]LeetCode143. 重排链表 | Reorder List

    Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You may not mod ...

  10. [Swift]LeetCode200.岛屿的个数 | Number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...