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

2、效率低下的HashTable容器
HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法时,其他线程访问HashTable的同步方法时,可能会进入阻塞或轮询状态。如线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,并且也不能使用get方法来获取元素,所以竞争越激烈效率越低。

3、ConcurrentHashMap分段锁技术
ConcurrentHashMap是Java 5中支持高并发、高吞吐量的线程安全HashMap实现。

我们以ConcurrentHashMap来说一下分段锁的含义以及设计思想,ConcurrentHashMap中的分段锁称为Segment,类似于HashMap(JDK7与JDK8中HashMap的实现)的结构,即内部拥有一个Entry数组,数组中的每个元素又是一个链表;同时又是一个ReentrantLock(Segment继承了ReentrantLock)。

当需要put元素的时候,并不是对整个hashmap进行加锁,而是先通过hashcode来知道他要放在哪一个分段中,然后对这个分段进行加锁,所以当多线程put的时候,只要不是放在一个分段中,就实现了真正的并行的插入。

但是,在统计size的时候,可就是获取hashmap全局信息的时候,就需要获取所有的分段锁才能统计。

分段锁的设计目的是细化锁的粒度,当操作不需要更新整个数组的时候,就仅仅针对数组中的一项进行加锁操作。

4、用法
模拟信息的发送和接收,场景是这样的:
服务器向客户端发送信息,要保证信息100%的发送给客户端,那么发给客户端之后,客户端返回一个消息告诉服务器,已经收到。当服务器一直没有收到客户端返回的消息,那么服务器会一直发送这个信息,直到客户端接收并确认该信息,这时候再删除重复发送的这个信息。

为了模拟该场景,这里写两个线程,一个是发送线程,一个是接收线程,把要发送的信息保存到线程安全的对象里面,防止发生线程安全问题,这里采用ConcurrentHashMap。

a、SendThread:信息重新发送类

package com.lynch.lock;import java.util.Map.Entry;/**   *** @author Lynch */
public class SendThread extends Thread {@Overridepublic void run() {try {sleep(6000);while (ConcurrentHashMapTest.pushMessage.size() > 0) {for (Entry<Integer, String> hashMap : ConcurrentHashMapTest.pushMessage.entrySet()) {System.out.println("消息id:" + hashMap.getKey()+ "未发送成功,在此重发:" + hashMap.getValue());}sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}}
}

b、ReceiveThread:信息接收类

package com.lynch.lock;import java.util.Map.Entry;/*** 接收发送过来的信息,并从内存中删除* * @author Administrator**/
public class ReceiveThread extends Thread {@Overridepublic void run() {try {for (int i = 0; i < 100000; i++) {sleep(2000);for (Entry<Integer, String> map : ConcurrentHashMapTest.pushMessage.entrySet()) {if (map.getKey() == i) {System.out.println("成功收到id为:" + map.getKey() + "返回的信息,删除该元素");ConcurrentHashMapTest.pushMessage.remove(map.getKey());}}System.out.println("内存对象中的元素数量为:" + ConcurrentHashMapTest.pushMessage.size());}} catch (InterruptedException e) {e.printStackTrace();}}
}

c、ConcurrentHashMapTest:主类入口

package com.lynch.lock;import java.util.concurrent.ConcurrentHashMap;/*** 模拟信息的发送和接收** @author Lynch*/
public class ConcurrentHashMapTest {public static ConcurrentHashMap<Integer, String> pushMessage = new ConcurrentHashMap<Integer, String>();public static void main(String[] args) {for (int i = 0; i < 5; i++) {pushMessage.put(i, "该消息是id为" + i + "的消息");}Thread sendThread = new SendThread();Thread receiveThread = new ReceiveThread();sendThread.start();receiveThread.start();for (int i = 5; i < 10; i++) {pushMessage.put(i, "该消息是id为" + i + "的消息");}}
}

这样两个线程可以轮流的进行各自的事情,并且不会造成数据安全的问题。用这种方式,再结合Androidpn的推送机制,会更加符合实际生产中的应用。

转载于:https://www.cnblogs.com/linjiqin/p/5131667.html

分段锁——ConcurrentHashMap相关推荐

  1. Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除

    文章目录 1. Java中的锁机制 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 可重入锁(递归锁) 1.5 读写锁 1.6 公平锁 1.7 非公平锁 1.8 共享锁 1.9 独占锁 1.1 ...

  2. 面试官:ConcurrentHashMap为什么放弃了分段锁?

    今天我们来讨论一下一个比较经典的面试题就是 ConcurrentHashMap 为什么放弃使用了分段锁,这个面试题阿粉相信很多人肯定觉得有点头疼,因为很少有人在开发中去研究这块的内容,今天阿粉就来给大 ...

  3. JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何 设计。

    jdk8 放弃了分段锁而是用了Node锁,减低锁的粒度,提高性能,并使用CAS操作来确保Node的一些操作的原子性,取代了锁. 但是ConcurrentHashMap的一些操作使用了synchroni ...

  4. 【转】ConcurrentHashMap分段锁原理

    前言:在分析ConcurrentHashMap的源码的时候,了解到这个并发容器类的加锁机制是基于粒度更小的分段锁,分段锁也是提升多并发程序性能的重要手段之一. 在并发程序中,串行操作是会降低可伸缩性, ...

  5. 我使出这“三板斧”(分段锁、哈希锁、弱引用锁)灭霸跑了......

    有同学说,学了Java那么多锁,还是没能锁住灭霸,本文教你"三板斧",锁灭霸足矣. 据说,没几个人能真正参透这"三板斧"的精髓,你是不是那个有缘人呢? 最近,在 ...

  6. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等...

    http://blog.51cto.com/13919357/2339446 Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容 ...

  7. go 并发安全map 分段锁实现

    一. 简言 1.1 go中的map不是并发安全的 1.2 go1.9版本之前,可以使用map+mutex的方式实现并发安全,但是每次操作,无论读取都要加锁,性能不太好 1.3 go 1.9之后,新增了 ...

  8. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

    Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁 / 非公平锁 可重入锁 / 不可重入锁 独享锁 / 共享锁 互 ...

  9. 2019最新拼多多Java面试题:幻影读+分段锁+死锁+Spring Cloud+秒杀

    拼多多Java一面 简短自我介绍 事务的ACID,其中把事务的隔离性详细解释一遍 脏读.幻影读.不可重复读 红黑树.二叉树的算法 平常用到哪些集合类?ArrayList和LinkedList区别?Ha ...

  10. 可重入锁/不可重入锁,公平锁/非公平锁,乐观锁/悲观锁,独享锁/共享锁,偏向锁/轻量级锁/重量级锁,分段锁,自旋锁

    在并发编程中,会涉及到各种各样的锁,这篇文章主要介绍各种锁的分类以及作用. 介绍的内容如下: 可重入锁/不可重入锁 公平锁/非公平锁 乐观锁/悲观锁 独享锁/共享锁 偏向锁/轻量级锁/重量级锁 分段锁 ...

最新文章

  1. C#编程概念系列(一):面向对象编程
  2. HDU 2102 A计划
  3. java 多线程间通讯_JAVA多线程间通讯常用实现方法解析
  4. python queue_Python-Queue 入门
  5. Oracle Schema Objects——Tables——TableType
  6. linux gunzip r .tar,Linux命令之文件归档、压缩、解压缩tar,gzip,gunzip,bzip2,bunz -电脑资料...
  7. 15个Linux Yum命令实例--安装/卸载/更新
  8. 设计模式——解释器模式
  9. dw1560_【兵哥小课堂】Big Sur安装情况汇总以及DW1820A/DW1560在Big Sur中的正确插入姿势...
  10. 【HDU1411】四面体的体积公式
  11. 十年前与十年后的我们,流着泪看完的经典语录!
  12. 崔希凡-javaWeb-笔记day07-day09(2016年7月26日23:17:27)
  13. IT6801FN图像质量调优
  14. 【Java】多人协同在线编辑Excel源代码及部署包
  15. 智能汽车里究竟“藏”有多少传感器?
  16. 计算机毕业设计ssm东湖爱心系统的众筹设计和实现t4a84系统+程序+源码+lw+远程部署
  17. 25、Java面向对象——抽象类和抽象方法、接口
  18. HCIP第九天笔记(OSPF的路由回馈、路由策略、以及配置指南)
  19. 【POI2013】bzoj3426 Tower Defence Game
  20. css单位vw vh,css3自适应布局单位vw,vh详解

热门文章

  1. 送书!60 本签名书!
  2. 移动开发者的未来在哪里?
  3. shell基础之case应用
  4. d3.js(v5.7)的node与数据匹配(自动匹配扩展函数)
  5. jmeter安装配置
  6. Divide Groups(分组)(二分图染色)
  7. bootstrap table 服务器端分页--ashx+ajax
  8. 关于Eclipse的常用快捷键
  9. HDU 4508 湫湫系列故事——减肥记I (2013腾讯编程马拉松初赛第一场)
  10. 2019牛客多校第六场H Pair(数位DP 多个数相关)题解