ConcurrentHashMap涉及的知识点:HashMap,HashTable,UnSafe,CAS,数组+链表,Segment,ReentrantLock(非公平锁,公平锁),红黑树。

为什么要有ConcurrentHashMap,而不直接使用HashMap和HashTable。

1.因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。

2.HashTable也是线程安全的,因为HashTable在很多方法上加了synchronized,会锁住整个map,所有访问HashTable的线程都必须竞争同一把锁,效率很低。

3.ConcurrentHashMap是线程安全的,在HashMap的基本上,加上了Segment数组(分段锁),假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率。

Segment数组是一种可重入锁ReentrantLock,每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。

4.JDK1.8到HashMap和ConCurrentHashMap进行了优化,当链接长度大于8时,会转换为红黑树。

ConcurrentHashMap的缺点:在统计size时,需要获取所有分段锁才能统计。

ReentrantLock原理:

ReentrantLock是基本Unsafe和CAS机制的,需要先对Unsafe和CAS了解。

UnSafe,基本JVM对物理内存直接操作,被认为是不安全的操作,JDK没有对外开放API。
CAS(compare and swap),CAS有3个操作数:内存值V、预期值A、要修改的新值B。当需要把A值修改成B时,只能当V=A时,才能修改成功。

  • 非公平锁:如果同时还有另一个线程进来尝试获取,那么有可能会让这个线程抢先获取;(默认为非公平锁)
  • 公平锁:如果同时还有另一个线程进来尝试获取,当它发现自己不是在队首的话,就会排到队尾,由队首的线程获取到锁。

a).获取锁流程A  

当一个线程获取锁时,先判断锁的状态是不是等于0(0代表可以获取锁),如果等于0,尝试使用CAS进用set写入,一旦成功,表明成功获取锁。

如果锁的状态不等于0,判断获取到锁的线程是否为当前线程,如果是当前线程,将状态+1,直接进入。这也就是可重入锁的实现原理。

final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}

b).获取锁流程B

当一个线程获取锁失败,进入队列队尾,进入队列后,如果前序节点是HEAD(表示列队里没有其它人需要获取锁),则CAS再尝试一次。

 否则,则会根据前序节点的状态判断是否需要阻塞。如果需要阻塞,则调用LockSupport的park方法阻塞该线程。

final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}

  

ConcurrentHashMap相关知识点的更多相关文章

  1. UITableView相关知识点

    //*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...

  2. Android开发涉及有点概念&相关知识点(待写)

    前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...

  3. IOS开发涉及有点概念&相关知识点

    前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...

  4. IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结

    添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...

  5. 学习记录013-NFS相关知识点

    一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...

  6. TCP/IP 相关知识点与面试题集

    第一部分:TCP/IP相关知识点 对TCP/IP的整体认 链路层知识点 IP层知识点 运输层知识点 应用层知识点 (这些知识点都可以参考:http://www.cnblogs.com/newwy/p/ ...

  7. Python开发一个csv比较功能相关知识点汇总及demo

    Python 2.7 csv.reader(csvfile, dialect='excel', **fmtparams)的一个坑:csvfile被csv.reader生成的iterator,在遍历每二 ...

  8. Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳

    前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...

  9. php正则相关知识点

    关于正则,其实简单就是搜索和匹配.php,java,python等都是支持正则的,php正则兼容perl.好多同学觉得正则比较难,比较抽象,其实正则是非常简单的,主要是一个熟悉和反复练习的结果,还有一 ...

随机推荐

  1. C/C++互相调用

    参考: http://www.cnblogs.com/Yogurshine/p/3913073.html http://blog.chinaunix.net/uid-24118190-id-29853 ...

  2. Greeplum 系列(七) 权限管理

    Greeplum 系列(七) 权限管理 一.角色管理 Role 分为用户(User)和组(Group),用户有 login 权限,组用来管理用户,一般不会有 login 权限.初始化 gp 时创建了一 ...

  3. 修复PlatformToolsets丢失问题(为VS2013以上版本安装VC90,VC100编译器)

    前段时间测试VS2017的IDE时不小心弄丢了 MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets 下的VC90以及VC100的编译 ...

  4. JSON.parse()和JSON.stringify()的使用

    parse用于从一个字符串中解析出json对象,如 var str = '{"name":"huangxiaojian","age":&qu ...

  5. C#进阶系列——WebApi 异常处理解决方案(转)

    出处:http://www.cnblogs.com/landeanfen/p/5363846.html 阅读目录 一.使用异常筛选器捕获所有异常 二.HttpResponseException自定义异 ...

  6. Linux网络(一)

    [root@localhost ~]# ifconfig eth0 Link encap:Ethernet HWaddr :0C:::F6: inet addr:172.17.4.128 Bcast: ...

  7. eclipse中maven install提示编码GBK的不可映射字符

    今天在eclipse中使用Maven编译项目源代码时,结果如下了如下的错误 在Java源码中没有提示任何报错,即便是改掉项目编码也是不行,如下图所示:

  8. (转)centos liveCD liveDVD netinstall minimal DVD1 DVD2 版本区别

    LiveCD 和 LiveDVD 是可以直接光盘运行系统,但不能安装,两者差别在于容量大小,dvd包含的软件要多一些. netinstall 是用于网络安装和系统救援的镜像文件. minimal 这个 ...

  9. Mysql错误: ERROR 1205: Lock wait timeout exceeded try restarting transaction解决办法

    select * from information_schema.INNODB_TRX;show full processlist;//找出目前连接的列表kill ID//根据ID kill掉

  10. C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件)

    string file =Application.StartupPath+@"\WinFrm_Main.exe";//运行程序位置 public Form1() { Initial ...