Tag: concurrenthashmap

ThreadLocal HashMap vs ConcurrentHashMap用于线程安全的未绑定缓存

我正在创建一个具有以下特征的memoization缓存: 高速缓存未命中将导致计算和存储条目 这个计算非常昂贵 这种计算是幂等的 无界限(条目从未删除)因为: 输入将导致最多500个条目 每个存储的条目都很小 缓存相对短缺(通常不到一小时) 总的来说,内存使用不是问题 将有成千上万的读取 – 在缓存的生命周期中,我预计99.9%+缓存命中 必须是线程安全的 什么会有一个优越的性能,或在什么条件下一个解决方案优于另一个解决方案? ThreadLocal HashMap: class MyCache { private static class LocalMyCache { final Map map = new HashMap(); V get(K key) { V val = map.get(key); if (val == null) { val = computeVal(key); map.put(key, val); } return val; } } private final […]

ConcurrentHashMap锁定

我在某地读过,在ConcurrentHashMap ,整个地图对象没有被锁定,而是在Map的一部分上进行锁定。 有人可以详细说明何时锁定进入图片? 是不是在读取Map时没有锁定,但在更新时只使用锁定?

ConcurrentHashMap构造函数参数?

我想知道构造ConcurrentHashMap的参数: initialCapacity默认为16(理解)。 loadFactor默认为0.75。 concurrencyLevel默认为16。 我的问题是: 应该使用什么标准来调整loadFactor上升或下降? 我们如何建立并发更新线程的数量? 应该使用什么标准来调整concurrencyLevel向上或向下? 另外: 良好的哈希码实现的标志是什么? (如果SO问题解决了这个问题,请链接到它。) 谢谢!

需要简单解释“锁定条带化”如何与ConcurrentHashMap一起使用

根据Java Concurrency in Practice,第11.4.3章说: 锁定拆分有时可以扩展到一组变量独立对象的分区锁定,在这种情况下,它被称为锁定条带化。 例如,ConcurrentHashMap的实现使用一个包含16个锁的数组,每个锁保护1/16的散列桶; 铲斗N由锁定N mod 16保护。 我仍然有理解和可视化锁条纹和铲斗机制的问题。 有人可以用很好理解的话来解释这个:) 提前致谢。

是否需要将ConcurrentHashMap包装在同步块中?

在ConcurrentHashMap( put() , remove()等)上的所有非retreival操作是否需要包装在synchronized(this)块中? 我知道所有这些操作都是线程安全的,所以这样做有什么好处/需要吗? 使用的唯一操作是put()和remove() 。 protected final Map mapDataStore = new ConcurrentHashMap(); public void updateDataStore(final String key, final String value) { … synchronized (this) { mapDataStore.put(key, value); } … }

锁定任意键的处理程序

我有代码实现任意键的“锁定处理程序”。 给定一个key ,它确保一次只有一个线程可以process该(或等于)密钥(这意味着调用externalSystem.process(key)调用)。 到目前为止,我有这样的代码: public class MyHandler { private final SomeWorkExecutor someWorkExecutor; private final ConcurrentHashMap lockMap = new ConcurrentHashMap(); public void handle(Key key) { // This can lead to OOM as it creates locks without removing them Lock keyLock = lockMap.computeIfAbsent( key, (k) -> new ReentrantLock() ); keyLock.lock(); try { someWorkExecutor.process(key); } finally { keyLock.unlock(); […]

ConcurrentHashMap崩溃使用JDK 8编译但是以JRE 7为目标的应用程序

我今天遇到了一个非常意想不到的错误,虽然我能够找到一种方法来解决整个问题,但我不确定我是否完全理解它为什么会这样做。 我正在使用的代码最初是用JDK 7环境编写的,当然是针对JRE 7.在代码中我使用的是ConcurrentHashMap ,需要迭代映射中的键。 为此,我使用了map.keySet() ,根据JavaDocs,它应返回Set 。 这工作正常,直到我们的构建环境切换到JDK8。 当我们转移到JDK8时,我确保在调用javac时调用1.7的目标/源。 当代码在想要遍历地图的键时开始失败时,我感到非常惊讶。 没有抛出任何错误,没有exception,线程只是停止了。 在做了一些研究后,我发现Java8的ConcurrentHashMap实现.keySet()方法返回一个KeySetView 。 我通过使用map.keySet()切换到使用map.keys()获取Enumeration来map.keys() 。 现在我对这个问题的猜测是,虽然项目是针对Java7编译的,因为使用了JDK8,Java8库被包含在内,但为什么在它出现不匹配时它没有抛出错误或exception? 正如这里所要求的是一段代码片段: class MapProcessing { private ConcurrentHashMap map = new ConcurrentHashMap(); public MapProcessing() { map.put(“First”,new Object()); map.put(“Second”,new Object()); map.put(“Third”,new Object()); } public void processing() { // when calling this type of loop causes a freeze on our system. for(String […]

在ConcurrentHashMap中修改值的首选方法是什么?

假设我有一个高读,低写并且需要存储应用程序数据的并发映射: ConcurrentMap map = new ConcurrentHashMap(); 然后,在启动期间和通过用户输入,数据将添加到地图中: public void createData(Data newData) { map.put(newId, newData); // etc… } 如果我需要更改数据,我应该: A)使Data类对象不可变,然后每次需要对Data对象进行更改时执行put操作: public void changeData(UUID oldId, Foo newInfo) { Data oldData = map.get(oldId); Data newData = new Data(oldData, newInfo); // Constructor for demo only map.put(newData); saveToDatabase(newData); } B)使用volatile字段,primefaces引用或最终并发字段使Data类对象可变但是线程安全,并根据需要简单地修改对象: public void changeData(UUID oldId, Foo newInfo) { Data data = […]

ConcurrentHashMap jdk 8使用TreeNodes而不是List ..为什么?

嗨,我知道在JDK 8之前ConcurrentHashMap的工作方式。我也理解了代码:它非常模块化,不太难理解。 JDK 8中的ConcurrentHashMap代码与之前的实现相比发生了很大变化。 因为这个问题被归类为过于宽泛,我现在会尝试非常具体。 CHMv8使用TreeBin(RedBlackTree的变体)来存储桶而不是链表。 所以我的问题是在链表上使用TreeBin的主要优势是什么? 源代码在这里

使用ConcurrentHashMap,何时需要同步?

我有一个ConcurrentHashMap,我在其中执行以下操作: sequences = new ConcurrentHashMap<Class, AtomicLong>(); if(!sequences.containsKey(table)) { synchronized (sequences) { if(!sequences.containsKey(table)) initializeHashMapKeyValue(table); } } 我的问题是 – 是否没有必要额外做 if(!sequences.containsKey(table)) 检查synschronized块内部,以便其他线程不会初始化相同的hashmap值? 也许检查是必要的,我做错了? 我正在做的事似乎有点傻,但我认为这是必要的。