一.线程不安全的HashMap

多线程环境下,使用HashMap进行put操作会引起死循环(jdk1.7 Entry链表形成环形数据结构),导致CPU利用率接近100%。

结构:数组 table[]+链表entry<k,v>
put 对key做hash
默认初始化数组长度 16
加载因子 0.75
扩容 大于16*0.75时
rehash
hash冲突:链表解决。原来的entry移出去,后来的进来,然后next指向原来的entry
线程不安全:多个线程扩容时闭环,引起死循环。
为什么会形成闭环:
线程1 A>B>C
线程2 B>A倒置。会变成A>B>A
解决:
1.8 红黑树:数组+链表+红黑树。阈值:8
hashmap扩容过程:
传入新的容量
初始化新的Entry数组,将数据转移到新的Entry数组里(遍历旧数组,取得每个元素,释放旧数组的引用,重新计算位置)
table属性引用新的entry数组
修改阈值
hash算法:取key的hashcode值,高位运算,取模运算
1.8的优化
1.resize时不需要重新计算hash,只要看看原来的hash新增的那个bit是0还是1。0的话索引没变,1的话索引变成原索引加oldcap。找到新数组下标,确定索引位置,增加随机性。
2.不会形成闭环,扩容时不再使用头插法改成尾插法。

二.效率低下的HashTable

多个线程访问HashTable的同步方法,会引起阻塞或轮询状态。

三.ConcurrentHashMap

jdk1.7 锁分段技术

数据分段存储,每段配一把锁,当一个线程访问其中一段时,其他线程也可访问其他段。

结构:Segment数组,每个数组下面维护HashEntry链表(存键值对)

http://www.importnew.com/28263.html

https://baijiahao.baidu.com/s?id=1607561719049934113&wfr=spider&for=pc

Java并发编程的艺术笔记(六)——HashMap、ConcurentHashMap的原理与实现的更多相关文章

  1. 多线程的通信和同步(Java并发编程的艺术--笔记)

    1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...

  2. Java并发编程的艺术笔记(五)——Java中的锁

    一.Lock接口的几个功能: 显示的获取和释放锁 尝试非阻塞的获取锁 能被中断的获取锁 超时获取锁 使用方式: Lock lock = new ReentrantLock(); lock.lock() ...

  3. Java并发编程的艺术笔记(七)——CountDownLatch、CyclicBarrier详解

    一.等待多线程完成的CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作,像加强版的join.(t.join()是等待t线程完成) 例: (1)开启多个线程 ...

  4. Java并发编程的艺术· 笔记(1)

    目录 1.volatile的原理 2.Synchonized 3.无锁-偏向锁-轻量级锁-重量级锁 4.Java实现原子操作 1.volatile的原理 如何保持可见性: 1)将当前处理器缓存行的数据 ...

  5. Java并发编程的艺术笔记(九)——FutureTask详解

    FutureTask是一种可以取消的异步的计算任务.它的计算是通过Callable实现的,多用于耗时的计算. 一.FutureTask的三种状态 二.get()和cancel()执行示意 三.使用 一 ...

  6. Java并发编程的艺术笔记(八)——线程池

    一.线程池的主要处理流程 ThreadPoolExecutor执行execute方法分下面4种情况. 1)如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(注意,执行这一步需要获 ...

  7. Java并发编程的艺术笔记(三)——Thread.join()

    t.join()方法只会使主线程进入等待池并等待t线程执行完毕后才会被唤醒.并不影响同一时刻处在运行状态的其他线程.它能够使得t.join()中的t优先执行,当t执行完后才会执行其他线程.能够使得线程 ...

  8. Java并发编程的艺术笔记(二)——wait/notify机制

    一.概述 一个线程修改了一个对象的值,另一个线程感知到变化从而做出相应的操作.前者是生产者,后者是消费者. 等待/通知机制,是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用 ...

  9. Java并发编程的艺术笔记(一)——volatile和syncronized关键字

    一.线程间的通信 volatile和syncronized关键字 volatile 修饰变量,告知任何对该变量的访问必须从共享内存获取,对它的改变必须同步刷新至共享内存,由此保证可见性. syncro ...

随机推荐

  1. Linux 测试IP和端口是否能访问

    一. 使用wget判断 wget是linux下的下载工具,需要先安装. 用法: wget ip:port 连接存在的端口 转自:https://blog.csdn.net/weixin_3768923 ...

  2. SpringMVC整体架构

    总结: 1. 用户发起请求到前端控制器(DispatchServlet): 2. 前端控制器没有处理业务逻辑的能力,需要找到具体的模型对象处理(Handler),到处理器映射器中查找Handler对象 ...

  3. luogu P4437 [HNOI/AHOI2018]排列

    luogu 问题本质是把\(a_i\)作为\(i\)的父亲,然后如果有环就不合法,否则每次要取数,要满足取之前他的父亲都被取过(父亲为0可以直接取),求最大价值 贪心想法显然是要把权值大的尽量放在后面 ...

  4. pt-archiver配置自动归档

    Mysql的数据归档通常使用percona的pt-archiver.通过shell脚本加crontab可以应对大多数场景下的数据自动归档. 安装 Percona Toolkit的安装不再赘述,请自行搜 ...

  5. commons Collections4 MultiMap

    MultiMap<String, Integer> multiMap = new MultiValueMap<>(); multiMap.put("A", ...

  6. Wayos网吧路由英雄联盟频繁掉线解决办法

    英雄联盟某些机器瞬间ping值飙升,然后一直掉线重连!研究好久,解决了,经验与大家分享 第一步,在路由器地址后加qos_ext.htm进入qos参数设置页面(如果出现不了设置界面请更新固件).比如:h ...

  7. javascript模板字符串(反引号)

    模板字面量 是允许嵌入表达式的字符串字面量. 你可以使用多行字符串和字符串插值功能.它们在ES2015规范的先前版本中被称为“模板字符串”. 语法 `string text`​`string text ...

  8. ffmpeg函数05__vcodec_decode_video2()

    vcodec_decode_video2()的作用是解码一帧视频数据

  9. 对比MySQL,你究竟在什么时候更需要MongoDB(转载)

    你期望一个更高的写负载 万美元的交易. 不可靠环境保证高可用性 设置副本集(主-从服务器设置)不仅方便而且很快,此外,使用MongoDB还可以快速.安全及自动化的实现节点(或数据中心)故障转移. 未来 ...

  10. HDU - 6393 Traffic Network in Numazu (基环树+树链剖分/LCA)

    题意:给定一个带权边无向基环树,有两种操作,一种是改变某个边的权值,另一种是询问两点间的最短路径. 可以对环进行缩点,以环为根建立一棵新树,并记录与环相连的所有点和环上的哪个点相连,将路径分为环外和环 ...