首页 \ 问答 \ ConcurrentHashMap条件替换(ConcurrentHashMap Conditional Replace)

ConcurrentHashMap条件替换(ConcurrentHashMap Conditional Replace)

我希望能够有条件地替换ConcurrentHashMap中的值。 那就是:

public class PriceTick {
   final String instrumentId;
   ...
   final long timestamp;
   ...

还有一个类(我们称之为TickHolder),它拥有一个ConcurrentHashMap(让我们只称它为map )。

我希望能够实现条件put方法,这样如果没有键的条目,则插入新的条目,但是如果存在现有条目,则只有在新PriceTick中的时间戳值时才插入新条目。大于现有的

对于老式的HashMap解决方案,TickHolder会有一个put方法:

public void add(PriceTick tick) {
   synchronized(map) {
      if ((map.get(tick.instrumentId) == null)
         || (tick.getTimestamp() > map.get(tick.instrumentId).getTimestamp()) )
         map.put(tick.instrumentId, tick);
      }
}

使用ConcurrentHashMap,人们可能希望删除同步并使用像replace这样的原子方法,但这是无条件的。 很明显,必须编写“条件替换”方法。

但是,由于测试和替换操作是非原子的,为了保证线程安全,它必须同步 - 但是我对ConcurrentHashMap源的初始读取使我认为外部同步和它们的内部锁定不会工作得非常好,所以至少每个执行结构更改的Map方法和包含类的执行必须由包含类同步......即使这样,我也会感到非常不安。

我想过继承ConcurrentHashMap,但这似乎是不可能的。 它使用具有默认访问权限的内部最终类HashEntry,因此尽管ConcurrentHashMap不是final,但它不可扩展。

这似乎意味着我必须回到实现TickHolder包含一个老派的HashMap才能编写我的条件替换方法。

所以,问题是:我对上述情况是否正确? 我(希望)是否遗漏了一些明显或微妙的东西,这会导致不同的结论? 我真的希望能够在这里使用那个可爱的条纹锁定机制。


I'd like to be able to conditionally replace a value in a ConcurrentHashMap. That is, given:

public class PriceTick {
   final String instrumentId;
   ...
   final long timestamp;
   ...

And a class (let's call it TickHolder) which owns a ConcurrentHashMap (let's just call it map).

I wish to be able to implement a conditional put method, so that if there's no entry for the key, the new one is inserted, but if there is an existing entry, the new one is inserted only if the timestamp value in the new PriceTick is greater than the existing one.

For an old-school HashMap solution, TickHolder would have a put method:

public void add(PriceTick tick) {
   synchronized(map) {
      if ((map.get(tick.instrumentId) == null)
         || (tick.getTimestamp() > map.get(tick.instrumentId).getTimestamp()) )
         map.put(tick.instrumentId, tick);
      }
}

With a ConcurrentHashMap, one would want to drop the synchronization and use some atomic method like replace, but that's unconditional. So clearly the "conditional replace" method must be written.

However, since the test-and-replace operation is non-atomic, in order to be thread safe, it would have to be synchronized - but my initial reading of the ConcurrentHashMap source leads me to think that external synchronization and their internal locks will not work very well, so at a very minimum, every Map method which performs structural changes and the containing class performs would have to be synchronized by the containing class... and even then, I'm going to be fairly uneasy.

I thought about subclassing ConcurrentHashMap, but that seems to be impossible. It makes use of an inner final class HashEntry with default access, so although ConcurrentHashMap is not final, it's not extensible.

Which seems to mean that I have to fall back to implementing TickHolder as containing an old-school HashMap in order to write my conditional replace method.

So, the questions: am I right about the above? Have I (hopefully) missed something, whether obvious or subtle, which would lead to a different conclusion? I'd really like to be able to make use of that lovely striped locking mechanism here.


原文:https://stackoverflow.com/questions/1395010
更新时间:2024-03-15 06:03

相关文章

更多

最新问答

更多
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • 电脑高中毕业学习去哪里培训
  • 电脑系统专业就业状况如何啊?
  • IEnumerable linq表达式(IEnumerable linq expressions)
  • 如何在Spring测试中连接依赖关系(How to wire dependencies in Spring tests)
  • Solr可以在没有Lucene的情况下运行吗?(Can Solr run without Lucene?)
  • 如何保证Task在当前线程上同步运行?(How to guarantee that a Task runs synchronously on the current thread?)
  • 在保持每列的类的同时向数据框添加行(Adding row to data frame while maintaining the class of each column)
  • 的?(The ? marks in emacs/haskell and ghc mode)
  • 一个线程可以调用SuspendThread传递自己的线程ID吗?(Can a thread call SuspendThread passing its own thread ID?)
  • 延迟socket.io响应,并“警告 - websocket连接无效”(Delayed socket.io response, and “warn - websocket connection invalid”)
  • 悬停时的图像转换(Image transition on hover)
  • IIS 7.5仅显示homecontroller(IIS 7.5 only shows homecontroller)
  • 没有JavaScript的复选框“关闭”值(Checkbox 'off' value without JavaScript)
  • java分布式框架有哪些
  • Python:填写表单并点击按钮确认[关闭](Python: fill out a form and confirm with a button click [closed])
  • PHP将文件链接到根文件目录(PHP Linking Files to Root File Directory)
  • 我如何删除ListView中的项目?(How I can remove a item in my ListView?)
  • 您是否必须为TFS(云)中的每个BUG创建一个TASK以跟踪时间?(Do you have to create a TASK for every BUG in TFS (Cloud) to track time?)
  • typoscript TMENU ATagParams小写(typoscript TMENU ATagParams lowercase)
  • 武陟会计培训类的学校哪个好点?
  • 从链接中删除文本修饰(Remove text decoration from links)