concurrenthashmap

Is it possible to have more than 32 locks in ConcurrentHashMap

点点圈 提交于 2019-12-03 07:15:18
I read ConcurrentHashMap works better in multi threading than Hashtable due to having locks at bucket level rather than map wide lock. It is at max 32 locks possible per map. Want to know why 32 and why not more than 32 locks. If you're talking about the Java ConcurrentHashMap , then the limit is arbitrary : Creates a new map with the same mappings as the given map. The map is created with a capacity of 1.5 times the number of mappings in the given map or 16 (whichever is greater), and a default load factor (0.75) and concurrencyLevel (16). If you read the source code it becomes clear that the

Does re-putting an object into a ConcurrentHashMap cause a “happens-before” memory relation?

眉间皱痕 提交于 2019-12-03 06:49:08
I'm working with existing code that has an object store in the form of a ConcurrentHashMap. Within the map are stored mutable objects, use by multiple threads. No two threads try to modify an object at once by design. My concern is regarding the visibility of the modifications between the threads. Currently the objects' code has synchronization on the "setters" (guarded by the object itself). There is no synchronization on the "getters" nor are the members volatile. This, to me, would mean that visibility is not guaranteed. However, when an object is modified it is re-put back into the map

Implementing a cache using a java ConcurrentHashMap

做~自己de王妃 提交于 2019-12-03 05:58:59
问题 I'd like to implement a simple caching of heavyweight objects in a web java application. But I can't figure out how to do it properly. Am I missing something or ConcurrentHashMap methods (putIfAbsent, ...) are not enough and additional synchronization is needed ? Is there a better simple API (In memory storage, no external config) to do this ? P. 回答1: If it is safe to temporarily have more than one instance for the thing you're trying to cache, you can do a "lock-free" cache like this: public

ConcurrentHashMap怎么保证安全的

最后都变了- 提交于 2019-12-03 05:31:57
HashMap是一个线程不安全的容器,当容量大于 总量*负载因子 发生扩容时可能会出现环形链表从而导致死循环 扩容就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中,在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示 因此引进了线程安全的容器 ConcurrentHashMap ConcurrentHashMap 在JDK1.7 和 JDK1.8中的实现有所不同 JDK1.7中的实现 先来看看1.7中数据结构实现的图示 由图中可以看出ConcurrentHashMap是由 Segment数组 , HashEntry数组 组成的。这里和 HashMap 一样,都是 数组+链表 的形式 ConcurrentHashMap采用了分段锁的技术,其中一个 Segement 就是一个Lock,其继承自 ReentrantLock ,这样当一个线程占用了锁访问一个 Segment 时,不会影响到其它的 Segment Segment 数组的意义就是将一个大的table分成多个小的table来进行加锁,而一个Segment存储的是HashEntry数组+链表,这和HashMap的数据结构一致 Segment的大小最多65536个,没有指定concurrencyLevel元素初始化

ConcurrentHashmap in JDK8 code explanation

冷暖自知 提交于 2019-12-03 03:30:52
I have been trying to understand the ConcurrentHashMap functions in JDK8, in contrast of how it was in JDK7 (which, in addition to the source code, can be found explained quite well by some nice folks out there such as Richard http://www.burnison.ca/articles/the-concurrency-of-concurrenthashmap ). It looks like have been changed quite a bit in JDK8 - e.g. there is no more 'segment' per se, but somehow I got a feeling that the changes are meant to make the code simpler? I'm having some difficulty to understand the method ConcurrentHashMap.putVal(...), especially the following section - is this

HashMap和Hashtable的区别

匿名 (未验证) 提交于 2019-12-03 00:43:02
二者继承的类与实现的接口 HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类(Dictionary类是一个已经被废弃的类)。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口。 HashTable比HashMap多了两个公开方法。一个是elements,这来自于抽象类Dictionary,鉴于该类已经废弃,所以这个方法也就没什么用处了。另一个多出来的方法是contains,这个多出来的方法也没什么用,因为它跟containsValue方法功能是一样的。 Null Key & Null Value HashMap是支持null键和null值的,而HashTable在遇到null时,会抛出NullPointerException异常。这并不是因为HashTable有什么特殊的实现层面的原因导致不能支持null键和null值,这仅仅是因为HashMap在实现时对null做了特殊处理,将null的hashCode值定为了0,从而将其存放在哈希表的第0个bucket中。 线程安全 Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步。 HashMap不是线程安全的

ConcurrentHashMap 产生NullPointerException

匿名 (未验证) 提交于 2019-12-03 00:41:02
今天测试在发给我一段报错日志后,根据日志定位到从ConcurrentHashMap 的缓存中get的时候,ConcurrentHashMap的底层抛出了空指针,当时感觉很奇怪为什么在get的时候产生空指针了呢? 模拟代码: ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); ........................................................ concurrentHashMap.get(传入的参数); 这个地方出现空指针,难道是传入的null 所以出现了空指针了,事实证明确实传入了null,但是我记得hashmap 是可以传入null 的呀? 为什么ConcurrentHashMap 却不行呢? 相应的去验证了一下,remove 方法发现也不能传入null 进去。 一、异常分析 FATAL EXCEPTION: main java.lang.NullPointerException at java.util.concurrent.ConcurrentHashMap.remove(ConcurrentHashMap.java: 921) 本以为是并发异常,后发现不对,因为ConcurrentHashMap已经使用继承自ReentrantLock的Segment

同步容器类和并发容器类

匿名 (未验证) 提交于 2019-12-03 00:27:02
1、同步容器类 包括Vector(实现了一个动态数组,和ArrayList相似,但两者是不同的)和Hashtable。 同步容器类的问题: 例如:Vector的getLast方法,和deleteLast方法,都会执行“先检查,后执行”操作,每个方法首先都获得数组的大小,然后通过结果来获取或删除最后一个元素。如果线程A调用getLast,线程B调用deleteLast,在线程A调用size和getLast之间,线程B删除了一个元素,则getLast会出现数组越界异常。同样,这种风险在对Vector中的元素进行迭代时仍然会出现。 解决方法:在客户端,将每个方法都进行加锁,使得每次只能有一个线程访问容器。 缺点:这样的话,同步容器类将所有对容器状态的访问都串行化,以实现它们的线程安全性,代价是严重降低并发性。 (1)Hashtable 链表+数组实现,初始容量11,扩容因子0.75。每一次扩容,为上一次容量的2倍+1. 源码: // 将“key-value”添加到Hashtable中 (2)Vector 数组实现,初始容量10。 Vector 当扩容容量增量大于0时、新数组长度为原数组长度+扩容容量增量、否则新数组长度为原数组长度的2倍。与ArrayList不同的就是两方面,分别是是否线程安全和扩容机制。 2、并发容器类(针对多个线程并发访问设计的)

ConcurrentHashMap的使用场景

匿名 (未验证) 提交于 2019-12-03 00:19:01
先大概的说一下几个map的区别: hashMap :读取快,插入慢,线程不安全 LinkedHashMap :读取快,插入慢 treeMap :排序 concurrentHashMap :线程安全,支持高并发的操作 当项目中的全局变量有多线程操作时需要用concurrentHashMap,若只是单线程则可以使用hashmap。 在多线程环境下使用hashMap会造成的问题: hashMap ,底层是数组+链表 结构,当两个线程同时插入需要扩容的时候,获得改map的size()大小不一样,则会报错。当有两个线程在读,第三个线程正好在对map扩容时,这两个线程就会进入死循环,cup占用率就会高。 concurrentHashMap ,线程安全,读写快,底层实现是一种以空间换时间的结构,创建的时候直接分了16个segment,每个segment实际上存储的还是哈希表,写入的时候先找到对应的segment,然后对segment加锁,写完,解锁。锁segment的时候其他segment还可以继续工作。 文章来源: ConcurrentHashMap的使用场景

ConcurrentHashMap JDK 8 when to use computeIfPresent

女生的网名这么多〃 提交于 2019-12-03 00:11:59
The new version of Concurrent Hash Map of jdk 8 has two new Methods. computeIfAbsent computeIfPresent putIfAbsent - Old method I understand the use cases of putIfAbsent and computeIfAbsent . But i am not sure of the scenarios when i will use computeIfPresent . Also why do i need putIfAbsent if i have computeIfPresent now. putIfAbsent do create atleast one extra instance of the value. Is the reason is only to have backward compatability? As mentioned in the other answer: Methods will always be kept for backward compatibility, even if there are new, more "powerful" methods introduced. Concerning