当前位置: 首页 > 面试题库 >

使用ConcurrentHashMap,何时需要同步?

卢和昶
2023-03-14
问题内容

我有一个ConcurrentHashMap,在其中执行以下操作:

sequences = new ConcurrentHashMap<Class<?>, AtomicLong>();

if(!sequences.containsKey(table)) {
    synchronized (sequences) {
        if(!sequences.containsKey(table))
            initializeHashMapKeyValue(table);
    }
}

我的问题是-是否有必要做多余的事情

if(!sequences.containsKey(table))

检查同步块内部,以便其他线程不会初始化相同的哈希图值?

也许检查是必要的,但我做错了吗?我在做什么似乎有点可笑,但我认为这是必要的。


问题答案:

*ConcurrentHashMap上的 *所有
操作都是线程安全的,但是线程安全的操作是不可组合的。您试图使原子操作成为一对操作:检查地图中的某些内容,如果不存在,请在其中放置某些内容(我认为)。因此,问题的答案是
肯定的 ,您需要再次检查,代码看起来还可以。



 类似资料:
  • 问题内容: 这样做,即ConcurrentHashMap(所有非retreival操作,等)需要在被包裹块?我知道所有这些操作都是线程安全的,因此这样做有真正的好处/需要吗?使用的唯一操作是和。 问题答案: 不,这样做会失去您的利益。您也可以使用with 或锁定整个表(这是在中包装操作时要执行的操作,因为隐含的监视器是整个对象实例。) 目的是通过允许在表上进行并发读/写而不锁定整个表来提高并发代码

  • 问题内容: jdk 8的并发哈希图的新版本具有两个新方法。 computeIfAbsent computeIfPresent putIfAbsent- 旧方法 我了解 putIfAbsent 和 computeIfAbsent 的用例。但是我不确定何时将使用 computeIfPresent 。另外,如果我现在有computeIfPresent,为什么还需要putIfAbsent。 putIfAb

  • 问题内容: 根据Java Concurrency in Practice,第11.4.3章说: 锁拆分有时可以扩展为对一组可变对象的独立对象进行分区锁,在这种情况下,这称为锁拆分。例如,ConcurrentHashMap的实现使用了一个由16个锁组成的数组,每个锁保护着1/16的哈希桶。桶N由锁N mod 16保护。 我仍然无法理解和可视化锁条和桶机制。有人可以用很好的理解力来解释这个问题吗:)

  • 我有一个并发HashMap,我在其中执行以下操作: 我的问题是——是否没有必要做额外的 检查synschronized块内部,以便其他线程不会初始化相同的hashmap值? 也许检查是必要的,但我做错了?我在做的事情似乎有点愚蠢,但我认为这是必要的。

  • 问题内容: 我有一个 Odata 查询: /ecommerceadmin/ODataService.svc/search?$select=status &$filter=id eq'test.com‘和名称eq’abc’ 如何在elasticsearch中实现代码以相应地获取数据。应使用 SearchSourceBuilder 中的 哪种 方法? 问题答案: 您可以轻松地摆脱一个和一个这样的查询:

  • 问题内容: 是用什么包装类之间的差异上,和? 它只是能够在迭代()的同时进行修改吗? 问题答案: 同步: 每种方法都使用对象级锁进行同步。因此,synchMap上的get和put方法获取一个锁。 锁定整个集合是性能开销。当一个线程保持该锁时,其他任何线程都不能使用该集合。 是在JDK 5中引入的。 在对象级别没有锁定,锁定的粒度要好得多。对于,锁定可以处于哈希图存储桶级别。 较低级别的锁定的结果是