Java实现选择性同步
我在应用程序中遇到一个问题,其中运行两个具有相同参数的线程,发生冲突。一种解决方案是使用同步块,但由于问题仅发生在具有相同参数的线程上,因此效率非常低。我想到的一种方法是使用并发映射将参数组合存储为键,将对象存储为值,每当线程开始操作时,它首先检查映射是否包含键(参数组合),如果是,则执行等待为该组合存储的对象。线程最后会从映射中删除该对象并对其调用通知。这种方法的问题是为相同的参数组合生成相同的对象。例如:如果线程1插入map,然后调用notify并删除它,线程2可能会退出等待,但其他线程永远不会出来,因为对象从map中丢失。
对于这个问题有不同的优雅方法吗?
I'm facing a problem in an application where two threads with same parameters are run, a conflict occurs. One solution was to use a synchronized block, but since the problem occurs only for threads with same params, it would be highly inefficient. One way I thought of was to use a concurrent map to store the param combination as key and an object as value, whenever a thread begins the operation it first checks if the map contains the key (param combination) and if so, it will do a wait on the object stored for that combination. The thread would at the end remove this object from the map and invoke notify on it. The problem with this approach is generating the same object for the same param combination. For ex: if thread1 inserts into map, and calls notify and removes it, thread2 may come out of wait, but other threads will never come out as the object is lost from the map.
Is there a different elegant approach to this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
创建参数组合池。每次需要保证一个线程正在运行时,请调用
Pool.acquire(params)
。像这样使用它:
使用漂亮的
hashCode
和equals
将参数包装在一个对象中。在主题中:
池:
这是一个想法。您需要为现实生活中的情况添加一些错误处理(
finally
中的release()
,在本例中处理Pool 中的 null
lock
.release() 等)。Create a pool of parameter combinations. Every time you need to guarantee one thread is running, call
Pool.acquire(params)
.Use it like this:
Wrap parameters in an object with nice
hashCode
andequals
.In Thread:
Pool:
That's one idea. You need to add some error handling for real life cases (
release()
infinally
, in this case handle nulllock
inPool.release()
, etc.).调用
notifyAll
而不是notify
,因此所有等待线程都会收到通知。为什么要从地图中删除同步对象?只需尝试获取该对象的锁,如果线程成功,则进入临界区,否则开始等待。您可以为该等待添加超时,因此如果线程在一段时间内无法获取锁,则会失败。这样你的代码就不会陷入死锁。
Call
notifyAll
instead ofnotify
, so all waiting threads will be notified. And why do you want to remove sync object from map? Just try to acquire lock on that object, if thread succeeds, it enters critical section, otherwise it starts to wait.You can add timeout to that wait, so if thread can't acquire lock for some period, it fails. This way your code won't go into deadlock.
如果您可以将参数(或其子集)表示为字符串,则可以在
interned
字符串上进行同步。If you can represent the parameters (or a subset of them) as a String, you can synchronize on the
interned
string.