当前位置: 首页 > 知识库问答 >
问题:

HashMap中的全映射锁以外的每键锁

金钊
2023-03-14

我在Java有一个很大map=concurrenthashMap(),而Key、Value是某种对象结构。假设这个映射的键集是keyset

现在我下面有一个计算程序。我的问题是我如何能够获得一个更好的性能通过不使用全地图锁。是否有任何选择,如使用每键锁或使用其他类型的数据结构?

考虑到这是一个很大的映射,使用every-key锁可能不是一种可接受的方法。

multiThread():
    for(0 to N):
        K = subset(keySet, m) where m is much smaller than keySet.size
        lock(map)
        for(key in K):
            result = func1(map.get(key), result)
        for(key in K):
            map.put(key, func2(map.get(key), result))
        releaseLock(map)

共有1个答案

空正豪
2023-03-14

在Java 8+中,ConcurrentHashMap作为一个compute()函数,它允许您对单个键html" target="_blank">执行原子的读-修改-写操作,因此您可以执行以下操作:

map.compute(key, () -> {
    //call func2 to compute new value and return it
});

但是,如果您想要对整个键集进行原子读取-修改-写入(因此首先要对您的键集进行迭代以计算结果,然后使用预先计算的结果更改所有这些键),那么ConcurrentHashMap中没有提供这种锁定的工具。

但是,您可以使用Guava的条纹锁,如下所示:

Striped<Lock> arrayOfLocks = Striped.lock(20);
// ...later on...
K = subset(keySet, m);
Iterable<Lock> toObtain = arrayOfLocks.bulkGet(K);
for (Lock l : toObtain) { lock it }
try {
   //do your modifications - your holding the stripe locks for all the keys
} finally {
   for (Lock l : toObtain) { unlock it }
}

锁条带化是将锁分配给数据结构的不同“区域”的概念-这里是通过密钥的hashCode完成的。

您需要非常小心地选择锁数组的大小,以便在太少的条带(您将锁住整个地图,并且比单个全局锁要慢)和太多的条带(您将抓取大量锁,这取决于K的大小)之间取得平衡。

Striped负责按相同的顺序返回锁,以便锁定同一组钥匙,这样您就可以避免用餐哲学家的问题。

 类似资料:
  • 假设您有一个表,如下所示: 可以看到列是表的主键和外键。是的,MySQL成功生成了这个表。 问题很简单,我将如何在JPA实体中映射这一点?我是否应该有映射到列的1个id和连接列的另一个字段?欢迎提出建议。

  • Hi编写Spring应用程序,使用Spring Security。这是我的用户和帐户角色数据库: 我的实体类: 当我尝试登录我的系统我有错误: Hibernate:选择userrolese0_. username作为username3_1_0_,userrolese0_. id作为id1_0_0_,userrolese0_. id作为id1_0_1_,userrolese0_. name作为nam

  • 问题内容: 我正在尝试建立一个PostgreSQL表,该表具有两个指向另一个表中相同主键的外键。 运行脚本时出现错误 sqlalchemy.exc.AmbiguousForeignKeysError:无法确定关系Company.stakeholder的父/子表之间的联接条件- 有多个链接表的外键路径。指定“ foreign_keys”参数,提供这些列的列表,这些列应被视为包含对父表的外键引用。 那

  • b)对Employee类中的ReferencedColumnName='department id'使用@ManyToOne和@JoinColumn。 建议采用哪种方法?还是这两种方法用于完全不同的问题?

  • 我正在尝试我们非主键作为外键在我的应用程序。场景如下:我有EMPLOYEE和EMPLOYEE_PROPERTIES表。Employee和Employee属性之间存在一对多的关系。下面是我的架构: 下面是我的hibernate映射XML:------------------------------- -------------员工属性------------------- 是否可以引用非主键作为外键

  • 我有以下MySQL表。这里的思想是轨道和课程是主键。并且轨道中的一个航向可能依赖于“同一轨道”中的另一个航向,因此我在(,)上创建了一个复合FK 但我在“depends_on_course_id column”中得到的结果都是空的,我猜getTrackCourse方法的映射有问题,但我不知道是什么?非常感谢任何帮助。