java并发初探ConcurrentHashMap
java并发初探ConcurrentHashMap
Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力。
1.8中ConcurrentHashMap的线程安全
1.volatile Node<k,v> []table保证数组的可见性
2.get操作没有加锁
3.put操作调用final V putVal(K key, V value, boolean onlyIfAbsent) ,在方法内部为Syncronized方法加锁,Syncronized据说在1.8得到优化
4.扩容的方法不是Syncronized,而在数据迁移的时候通过Syncronized迁移数据
5.多线程putVal(K key, V value, boolean onlyIfAbsent),通过helpTransfer帮助数组扩容(binCount),然后继续添加元素 (binCount!=0跳出)
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
6.多线程下扩容,因为扩容是多线程共同进行,而且锁住了首节点,能够快速扩容
else if ((f = tabAt(tab, i)) == null)//锁住节点
advance = casTabAt(tab, i, null, fwd);
else if ((fh = f.hash) == MOVED)
advance = true; // already processed
else {
//执行该节点的扩容数据移动
synchronized (f) {
7.ConcurrentHashMap取消了Segment分段锁,采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树。Java 8在链表长度超过一定阈值(8)时将链表(寻址时间复杂度为O(N))转换为红黑树(寻址时间复杂度为O(log(N)))
synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。
例子
package com.java.javabase.thread.collection;
import com.java.javabase.innerclass.DoThis;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author
*/
@Slf4j
public class ConcurrentHashMapTest {
public static int cap = 5;
public static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
//public static HashMap<Integer, String> map = new HashMap<>();//会出现ConcurrentModificationException
public static void main(String[] args) {
InnerThread t1= new InnerThread("t1");
InnerThread t2= new InnerThread("t2");
t1.start();
t2.start();
//printAll(map);
}
static class InnerThread extends Thread {
public InnerThread(String name)
{
super(name);
}
@Override
public void run() {
for (int i = 0; i < cap; i++) {
try {
map.put(i, String.valueOf(i));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
printAll(map);
}
}
}
static void printAll(Map<Integer, String> map) {
//Set<Map.Entry<Integer, String>> entrySet=map.entrySet();
Set entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();
while (it.hasNext()) {
Map.Entry entry = it.next();
log.info("thread {}: ,key {} value {}", Thread.currentThread().getName(),
entry.getKey(), entry.getValue());
}
}
}
java并发初探ConcurrentHashMap的更多相关文章
- java并发初探ConcurrentSkipListMap
java并发初探ConcurrentSkipListMap ConcurrentSkipListMap以调表这种数据结构以空间换时间获得效率,通过volatile和CAS操作保证线程安全,而且它保证了 ...
- java并发初探ThreadPoolExecutor拒绝策略
java并发初探ThreadPoolExecutor拒绝策略 ThreadPoolExecuter构造器 corePoolSize是核心线程池,就是常驻线程池数量: maximumPoolSize是最 ...
- java并发初探CyclicBarrier
java并发初探CyclicBarrier CyclicBarrier的作用 CyclicBarrier,"循环屏障"的作用就是一系列的线程等待直至达到屏障的"瓶颈点&q ...
- java并发初探CountDownLatch
java并发初探CountDownLatch CountDownLatch是同步工具类能够允许一个或者多个线程等待直到其他线程完成操作. 当前前程A调用CountDownLatch的await方法进入 ...
- java并发初探ReentrantWriteReadLock
java并发初探ReentrantWriteReadLock ReenWriteReadLock类的优秀博客 ReentrantReadWriteLock读写锁详解 Java多线程系列--" ...
- Java并发容器--ConcurrentHashMap
引子 1.不安全:大家都知道HashMap不是线程安全的,在多线程环境下,对HashMap进行put操作会导致死循环.是因为多线程会导致Entry链表形成环形数据结构,这样Entry的next节点将永 ...
- Java并发分析—ConcurrentHashMap
LZ在 https://www.cnblogs.com/xyzyj/p/6696545.html 中简单介绍了List和Map中的常用集合,唯独没有CurrentHashMap.原因是CurrentH ...
- 深入理解Java并发容器——ConcurrentHashMap
目录 重要属性和类 put 为什么java8后放弃分段锁,改用CAS和同步锁 初始化 addCount 扩容 树化 参考 重要属性和类 sizeCtl 容量控制标识符,在不同的地方有不同用途,而且它的 ...
- Java 并发实践 — ConcurrentHashMap 与 CAS
转载 http://www.importnew.com/26035.html 最近在做接口限流时涉及到了一个有意思问题,牵扯出了关于concurrentHashMap的一些用法,以及CAS的一些概念. ...
随机推荐
- vue中,实现锚点定位及跳转(url不发生变化)
<div class="footer" @click="returnTop"> methods:{ returnTop:function(){ do ...
- enviroment linux jdk and git and maven
#java_home export JAVA_HOME=/usr/local/java/jdk1.8.0_211 export JRE_HOME=$JAVA_HOME/jre export CLASS ...
- Python分析盘点2019全球流行音乐:是哪些歌曲榜单占领了我们?
写在前面:圣诞刚过,弥留者节日气息的大家是否还在继续学习呐~在匆忙之际也不忘给自己找几首好听的歌曲放松一下,缠绕着音乐一起来看看关于2019年流行音乐趋势是如何用Python分析的吧! 昨天下午没事儿 ...
- lena全身像
数字图像处理中,Lena(Lenna)是一张被广泛使用的标准图片,特别在图像压缩的算法研究中 (为什么用这幅图,是因为这图的各个频段的能量都很丰富:即有低频(光滑的皮肤),也有高频(帽子上的羽毛),很 ...
- Java中引用类型、对象的创建与销毁
引用类型 在java中,除了基本数据类型之外的,就是引用数据类型了,引用指的是对象的一个引用,通过引用可以操作对象,控制对象,向对象发送消息. 简单来说,引用可以访问对象的属性,并调用对象的方法 创建 ...
- elasticsearch数据组织结构
elasticsearch数据组织结构 1. mapping 1.1. 简介 mapping:意为映射关系,特别是指组织结构.在此语境中可理解为数据结构,包括表结构,表约束,数据类型等 ...
- ubuntu循环登录
ubuntu12.04管理员账户登录不了桌面,只能客人会话登录 登录管理员账户时,输入密码后,一直在登录界面循环 费了好大劲啊,一上午的时间,终于搞定了,哈哈哈 ctrl+alt+f1 ,切换到tty ...
- codeforces round#613
A题:输出n+1: B题: 题意:就是给n个数,a人全拿,b人拿连续的子段和,如果b人比a人大于等于的话输出NO,反之输出YES 思路:最大子段和,比赛的时候忘记 ll 和 字段和不是遇到负数就重置. ...
- springboot集成过滤器
封装自定义接口filter 包含两个方法,第一个过滤的路径数组,第二个为过滤器执行的顺序.spring boot 会按照order值的大小,从小到大的顺序来依次过滤. package com.thee ...
- Community Cloud零基础学习(一)启用以及简单配置
本篇参考: https://trailhead.salesforce.com/en/content/learn/trails/communities https://trailhead.salesfo ...