我正在尝试了解如何使用actor解决dining philosophers problem。如果您不知道,问题的关键在于线程需要获得两个锁才能继续...并且有多个线程争夺这两个锁。
这是我可以使用演员建模的一种方式:
# asynchronously request locks from 2 forks (both forks are actors)
lock1 = fork1.future.lock
lock2 = fork2.future.lock
if lock1 && lock2 # wait to get both locks
... critical section
end
但我认为如果两个线程各有一个锁并等待另一个线程放弃锁定,这将导致死锁。
一般来说,我如何使用actor以原子方式访问两个资源?
答案 0 :(得分:0)
答案 1 :(得分:0)
actor的想法是不要有任何锁定,以免由于不正确的同步而遇到死锁或其他问题。因此,将锁与演员结合使用可以让你重新回到演员想要绕过的那种问题。问题在于存在争用免费分叉并因此共享数据的竞争。没有任何共享数据时,演员工作得很好。您可以共享简单的共享数据,例如使用java.util.concurrent.ConcurrentHashMap,它是无锁且足以解决此类问题。
现在ConcurrentHashMap不会发送一个事件,以防一些哲学家放下一个分支。我曾经实现了一个简单的ConcurrentMap,让你注册事件,参见ConcurrentEventMap。查看MemoizingEventCalculatorTest以了解它是如何使用的。要运行此代码,需要JDK8,您可以从here下载。
这个ConcurrentEventMap更像是一个临时的kludge。我正在努力使用ScalaSTM获得更好的实现(请参阅http://nbronson.github.io/scala-stm/)。这也可能是您的选择。