concurrenthashmap

如何编写线程安全但可伸缩的类

落花浮王杯 提交于 2020-03-06 16:41:19
编写线程安全类时,主要问题是将数据分为多个独立的部分,并为这些部分选择合适的大小。如果部分太小,则我们的类不是线程安全的。如果部件太大,则该类不可扩展。 让我们看一个进一步说明这种情况的示例: 一个例子 假设我们要跟踪一个城市中有多少人。我们要支持两种方法,一种是获取当前居住在城市中的人数,另一种是将一个人从一个城市转移到另一个城市。因此,我们有以下界面: 由于我们要从多个线程并行使用此接口,因此必须选择实现此接口的选项。使用该类 java.util.concurrent. ConcurrentHashMap 或使用该类 java.util.HashMap 和一个锁。这是使用类的实现 java.util.concurrent.ConcurrentHashMap : 方法移动使用线程安全方法计算来减少源城市中的计数。然后,使用计算来增加目标城市中的计数。count方法使用线程安全方法 get 。 这是使用该类的实现 java.util.HashMap : 该方法 move 还使用该方法 compute 来增加和减少源城市和目标城市中的计数。仅在这一次,因为该 compute 方法不是线程安全的,所以两个方法都被同步块包围。该 count 方法 get 再次使用被同步块包围的方法。 两种解决方案都是线程安全的。 但是在使用的解决方案中 ConcurrentHashMap

Java常见面试题

你说的曾经没有我的故事 提交于 2020-03-04 04:24:06
Java开发岗位面试常问题 一、Java基础 1、String类为什么是final的. 2、HashMap的源码,实现原理,底层结构. 3、说说你知道的几个Java集合类:list、set、queue、map实现类咯... 4、描述一下ArrayList和LinkedList各自实现和区别 5、Java中的队列都有哪些,有什么区别. 6、反射中,Class.forName和classloader的区别 7、Java7、Java8的新特性(baidu问的,好BT) 8、Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高 9、Java内存泄露的问题调查定位:jmap,jstack的使用等等 10、string、stringbuilder、stringbuffer区别 11、hashtable和hashmap的区别 13、异常的结构,运行时异常和非运行时异常,各举个例子 14、String a= "abc" String b = "abc" String c = new String("abc") String d = "ab" + "c" .他们之间用 == 比较的结果 15、String 类的常用方法 16、Java 的引用类型有哪几种 17、抽象类和接口的区别 18、java的基础类型和字节大小. 19

Java集合

江枫思渺然 提交于 2020-03-03 15:40:34
容器主要包括collection和map两种,map不是collection(set,list,queue)里的 Set treeset hashset linkedhashset List arraylist linkedlist vector copyonwritearraylist Quque linkedlist priorityquque Map hashmap linkedhashmap concurrenthashmap list可以允许重复对象和插入多个null值,而set不允许;list容器是有序的,而set容器是无序的 Arraylist基于数组实现,开始不分配内存,第一个加进去的时候才分配,默认10个。添加和删除元素都需要赋值大量对象。 Collections.synchronizedList(new ArrayList())后如果要用iterator还是需要给iterator加同步锁,因为这个方法没对Iterator加锁,对add啥的倒是加了。 CopyOnWriteArrayList适合读多写少的。因为它支持读写同时进行,但是写的时候要在新的数组里写然后原始数组指向新的数组,时间空间都不占优。而且可能出现实时性差的问题,写的过程中读不到最新的。 适配器模式(不能用基本类型数组做参数,可以用包装类型)和迭代器模式 HashMap一个Entry的数组

ConcurrentHashMap解析

六月ゝ 毕业季﹏ 提交于 2020-03-02 11:23:18
ConcurrentHashMap采用分段锁技术,跟Hashtable相比,它不是锁全部数据,而是锁一部分数据。ConcurrentHashMap默认并发是16。 结构图 jdk1.7 数据结构采用Segment数组 + HashEntry数组的方式进行实现。初始化时候,计算出Segment数组的大小ssize和每个Segment中HashEntry数组大小cap,ssize初始化大小为16,最终结果根据 初始化容量initialCapacity进行计算,默认只会初始化第一个Segment和两个size的table 。Segment继承了 ReentrantLock,所以带锁的功能。 put put插入数据时,根据key的hash值,在segment数组中找到相应的位置,如果相应位置的segment未初始化,则通过CAS赋值,接着执行Segment的put方法通过加锁的方式插入数据。其实就是先找到segment,再找到table,如果此时已经有值,计算hash和equals,如果都相等则替换value,否则挂在链表最后。 场景:线程A和线程B同时执行相同Segment对象的put方法 1、线程A执行tryLock()方法成功获取锁,则把HashEntry对象插入到相应的位置; 2、线程B获取锁失败,则执行scanAndLockForPut()方法

ConcurrentHashMap源码解析

北慕城南 提交于 2020-03-02 10:33:41
ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现 ConcurrentHashMap在并发编程的场景中使用频率非常之高,本文就来分析下ConcurrentHashMap的实现原理,并对其实现原理进行分析(JDK1.7). ConcurrentHashMap实现原理   众所周知,哈希表是中非常高效,复杂度为O(1)的数据结构,在Java开发中,我们最常见到最频繁使用的就是HashMap和HashTable,但是在线程竞争激烈的并发场景中使用都不够合理。    HashMap :先说HashMap,HashMap是 线程不安全 的,在并发环境下,可能会形成 环状链表 (扩容时可能造成,具体原因自行百度google或查看源码分析),导致get操作时,cpu空转,所以,在并发环境中使用HashMap是非常危险的。    HashTable : HashTable和HashMap的实现原理几乎一样,差别无非是 1.HashTable不允许key和value为null;2.HashTable是线程安全的。 但是HashTable线程安全的策略实现代价却太大了,简单粗暴,get/put所有相关操作都是synchronized的,这相当于给整个哈希表加了一把 大锁 ,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞

HashMap的工作原理及HashMap和Hashtable的区别

我怕爱的太早我们不能终老 提交于 2020-03-01 14:59:10
HashMap的工作原理是近年来常见的Java面试题。几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此特殊呢?是因为这道题考察的深度很深。这题经常出现在高级或中高级面试中。投资银行更喜欢问这个问题,甚至会要求你实现HashMap来考察你的编程能力。ConcurrentHashMap和其它同步集合的引入让这道题变得更加复杂。让我们开始探索的旅程吧! 先来些简单的问题 “你用过HashMap吗?” “什么是HashMap?你为什么用到它?” 几乎每个人都会回答“是的”,然后回答HashMap的一些特性,譬如HashMap可以接受null键值和值,而Hashtable则不能;HashMap是非synchronized;HashMap很快;以及HashMap储存的是键值对等等。这显示出你已经用过HashMap,而且对它相当的熟悉。但是面试官来个急转直下,从此刻开始问出一些刁钻的问题,关于HashMap的更多基础的细节。面试官可能会问出下面的问题: “你知道HashMap的工作原理吗?” “你知道HashMap的get()方法的工作原理吗?” 你也许会回答“我没有详查标准的Java API,你可以看看Java源代码或者Open JDK。”“我可以用Google找到答案。”

HashMap和ConcurrentHashMap

大城市里の小女人 提交于 2020-03-01 09:36:03
目录 HashMap Java7中HashMap(数组+单向链表) ​ Java8中的HashMap(数组+链表+红黑树) ConcurrentHashMap Java7中的ConcurrentHashMap Java8中的ConcurrentHashMap(引入红黑树) HashMap HashMap 根据键的 hashCode 值存储数据 ,大多数情况下可以直接定位到它的值,因而具有很快 的访问速度,但遍历顺序却是不确定的。 HashMap 最多只允许一条记录的键为 null ,允许多条记 录的值为 null。 HashMap 非线程安全 ,即任一时刻可以有多个线程同时写 HashMap,可能会导 致数据的不一致。 如果需要满足线程安全, 可以用 Collections 的 synchronizedMap 方法使 HashMap 具有线程安全的能力 ,或者 使用 ConcurrentHashMap 。 Java7中HashMap(数组+单向链表) 大方向上, HashMap 里面是一个 数组 ,然后数组中每个元素是一个 单向链表 。上图中,每个绿色 的实体是嵌套类 Entry 的实例, Entry 包含四个属性: key, value, hash 值和用于单向链表的 next 。 1. capacity:当前数组容量,始终保持 2^n,可以扩容,扩容后数组大小为当前的 2 倍。

HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的原理和区别

ぐ巨炮叔叔 提交于 2020-02-26 00:00:26
HashMap 是否是线程安全的,如何在线程安全的前提下使用 HashMap,其实也就是 HashMap , Hashtable , ConcurrentHashMap 和 synchronized Map 的原理和区别。当时有些紧张只是简单说了下HashMap不是线程安全的;Hashtable 线程安全,但效率低,因为是 Hashtable 是使用 synchronized 的,所有线程竞争同一把锁;而 ConcurrentHashMap 不仅线程安全而且效率高,因为它包含一个 segment 数组,将数据分段存储,给每一段数据配一把锁,也就是所谓的锁分段技术。当时忘记了 synchronized Map 和解释一下 HashMap 为什么线程不安全。面试结束后问了下面试官哪里有些不足,面试官说上面这个问题的回答算过关,但可以在深入一些或者自己动手尝试一下。so~~~虽然拿到了 offer,但还是再整理一下,不能得过且过啊。 为什么HashMap是线程不安全的 总说 HashMap 是线程不安全的,不安全的,不安全的,那么到底为什么它是线程不安全的呢?要回答这个问题就要先来简单了解一下 HashMap 源码中的使用的 存储结构 (这里引用的是 Java 8 的源码,与7是不一样的)和它的 扩容机制 。 HashMap的内部存储结构 下面是 HashMap 使用的存储结构: 1 2

Behavior of entrySet().removeIf in ConcurrentHashMap

人走茶凉 提交于 2020-02-18 05:50:32
问题 I would like to use ConcurrentHashMap to let one thread delete some items from the map periodically and other threads to put and get items from the map at the same time. I'm using map.entrySet().removeIf(lambda) in the removing thread. I'm wondering what assumptions I can make about its behavior. I can see that removeIf method uses iterator to go through elements in the map, check the given condition and then remove them if needed using iterator.remove() . Documentation gives some info about

新问题整理(高并发)

微笑、不失礼 提交于 2020-02-12 20:57:04
一、HashMap 是不是线程安全? HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中, 在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的 (多线程会导致 HashMap 的 node 链表形成环状的数据结构产生死循环) 1.1、如何变得安全: Hashtable:通过 synchronized 来保证线程安全的,独占锁,悲观策略。吞吐量较低,性能较为低下 ConcurrentHashMap:JUC 中的线程安全容器,高效并发。ConcurrentHashMap 的 key、value 都不允许为 null 1.2、jdk1.8相对于jdk1.7的优化 由 数组+链表 的结构改为 数组+链表+红黑树。 拉链过长会严重影响hashmap的性能,所以1.8的hashmap引入了红黑树,当链表的长度大于8时,转换为红黑树的结构 优化了高位运算的hash算法:h^(h>>>16) 将hashcode无符号右移16位,让高16位和低16位进行异或。 二、ConcurrentHashMap 的实现方式 1.7