【问题标题】:Thread safe container for <key, value> pair<key, value> 对的线程安全容器
【发布时间】:2014-07-01 05:54:32
【问题描述】:

我需要一个包含 [key, Value] 对的容器。

这里,key = Integer, Value = User Defined class object

多个线程正在尝试在上述容器中添加 [key, Value] 对。

如果容器中已经存在键,我想通过检查一些条件来更新值。

最后,我希望容器按 Key 排序。

我的努力-

我使用这个synchronizedSortedMapSorted Map 完成上述任务。

SortedMap<Integer, USER_DEFINED_OBJECT> m = Collections.synchronizedSortedMap(new TreeMap<Integer, USER_DEFINED_OBJECT>());

这有助于我在上面的容器上同时添加对。

而且,是的,如果密钥已经存在,那么我检查一些条件,然后继续。

我的方法总是线程安全的吗?如果没有,请纠正我。

更新

  1. USER_DEFINED_OBJECT 有一些字段索引。
  2. 在添加时,我正在检查键是否已经存在,然后根据上面提到的(在第 1 点)提交的“索引”比较当前的 USER_DEFINED_OBJECT 和已经存在的 USER_DEFINED_OBJECT。如果当前的“索引”大于更新。

【问题讨论】:

  • 只要同步整个“添加、更新”过程而不仅仅是添加,这应该是线程安全的。
  • ConcurrentHashMap 是解决方案,然后按照您想要的顺序对其进行排序。看看this
  • 要判断您的代码是否是线程安全的,请提供其余部分。特别是检查条件。您可能有竞争条件。
  • @ChrisK 请检查更新的部分。

标签: java multithreading treemap


【解决方案1】:

使用 java.util 包中的 ConcurrentHashMap,阅读 API ConcurrentHashMap

【讨论】:

  • 但是 Hash Map 不会以排序方式给我输出。
  • @Loha :是的,对,我的错。那么TreeMap就是一条出路。
【解决方案2】:

java.util.concurrent.ConcurrentSkipListMap

一个可扩展的并发 ConcurrentNavigableMap 实现。地图根据其键的自然顺序排序,或者由地图创建时提供的 Comparator 排序,具体取决于使用的构造函数。 此类实现 SkipLists 的并发变体,为 containsKey、get、put 和 remove 操作及其变体提供预期的平均 log(n) 时间成本。插入、删除、更新和访问操作由多个线程安全地并发执行。迭代器是弱一致的,返回的元素反映了在迭代器创建时或之后的某个时刻映射的状态。它们不会抛出 ConcurrentModificationException,并且可以与其他操作同时进行。升序键排序视图及其迭代器比降序视图更快。

【讨论】:

  • 感谢您的回答。但我对某一点感到困惑,是的,我们可以同时添加多个条目。但是添加我需要检查的任何条目,无论该条目是否已经存在。我认为可能存在一种情况,当一个线程检查条件时,它发现容器中不存在对,去放吧。但同时其他一些线程为该键设置了 som 值。这种情况曾经发生过吗?
  • 这取决于您的应用程序的逻辑。如果你需要你应该检查。 :-)。描述情况可能发生。此类具有 putIfAbsent 方法 - 仅当它不存在时才添加对。
【解决方案3】:

并发集合允许您以事务的形式调用putremove 等方法。因此它是线程安全的。

据我了解,您添加新 [key, value] 对的情况如下:

  1. 检查映射是否已经存在
  2. 如果没有,就添加它
  3. 如果是,请根据检查更新映射中现有的value

我怀疑是否存在以线程安全的方式为您执行此操作的实现。如果我正确理解了您的用例,您将需要自己添加一些手动同步以使更新步骤事务性

【讨论】:

  • 是的,我通过在容器对象上放入同步块来将检查条件和更新容器作为原子。
猜你喜欢
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多