ConcurrentHashMap相关知识点
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相关知识点的更多相关文章
- UITableView相关知识点
//*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...
- Android开发涉及有点概念&相关知识点(待写)
前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...
- IOS开发涉及有点概念&相关知识点
前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...
- IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结
添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...
- 学习记录013-NFS相关知识点
一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...
- TCP/IP 相关知识点与面试题集
第一部分:TCP/IP相关知识点 对TCP/IP的整体认 链路层知识点 IP层知识点 运输层知识点 应用层知识点 (这些知识点都可以参考:http://www.cnblogs.com/newwy/p/ ...
- Python开发一个csv比较功能相关知识点汇总及demo
Python 2.7 csv.reader(csvfile, dialect='excel', **fmtparams)的一个坑:csvfile被csv.reader生成的iterator,在遍历每二 ...
- Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳
前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...
- php正则相关知识点
关于正则,其实简单就是搜索和匹配.php,java,python等都是支持正则的,php正则兼容perl.好多同学觉得正则比较难,比较抽象,其实正则是非常简单的,主要是一个熟悉和反复练习的结果,还有一 ...
随机推荐
- UI / UX设计师如何玩转用户心理学原理?
以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 众所周知,心理学在APP的用户体验设计中起着非常重要的作用.通过了解我们的设计是如何被感知的,我们可 ...
- iOS密码输入框的实现
[iOS密码输入框的实现] 就是一个UITextField,把属性 UITextField.secureTextEntry设置为Yes即可.此种UI效果为iOS默认效果.
- 简明的sql优化
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- docker查看挂载目录命令
docker inspect -f "{{.Mounts}}" 692691b7416 692691b7416为containerId
- windows phone 8.0 app 移植到windows10 app笔记
8.0 public class Convisibility : IValueConverter { public object Convert(object value, Type targetTy ...
- CSS文字大小单位PX、EM的区别
◆px像素(Pixel)是相对长度单位,像素px是相对于显示器屏幕分辨率而言的.(引自CSS2.0手册)◆em是相对长度单位,相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则 ...
- TestNG学习笔记目录
学习TestNG主要用于GUI自动化测试使用,学习目录随进度不断更新.文档内容主要是翻译官方doc,同时加入自己的理解和案例.如有理解偏差欢迎指正 一.TestNG Eclipse plug-in 安 ...
- Android - Telephony API 1.5
TelephonyManager: 1. public String getDeviceSoftwareVersion() : software version number, ex: IMEI/SV ...
- VS2013如何添加LIb库及头文件的步骤
在VS工程中,添加c/c++工程中外部头文件及库的基本步骤: 1.添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录. 2.添加文件引用 ...
- 查域名对应的ip的命令:Nslookup
使用Nslookup命令可查询域名对应的ip,如下所示