1

我试图了解如何使用演员解决哲学家就餐问题。如果您不知道,问题的症结在于,一个线程需要获得两个锁才能继续执行……并且有多个线程在争夺这两个锁。

这是我可以使用演员对此进行建模的一种方法:

# 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

但是我认为如果两个线程各有一个锁并且正在等待另一个线程放弃它的锁,这将导致死锁。

一般来说,我将如何建模使用演员以原子方式访问两个资源?

4

2 回答 2

0

这里有一个使用Akka actor用 Scala 编写的解决方案的良好实现。

于 2013-05-13T21:49:12.103 回答
0

Actor 的想法是不要有任何锁,以免由于不正确的同步而陷入死锁或其他问题。因此,将锁与演员一起使用可以让你回到演员打算解决的问题。问题是免费分叉和共享数据之间存在竞争。当没有任何共享数据时,Actor 工作得很好。您可以共享简单的共享数据,例如使用 java.util.concurrent.ConcurrentHashMap,它是无锁的,足以解决此类问题。

现在 ConcurrentHashMap 不会发送事件以防某些哲学家放下叉子。我曾经实现了一个简单的 ConcurrentMap ,让您注册事件,请参阅ConcurrentEventMap。看看MemoizingEventCalculatorTest看看它是如何使用的。运行此代码需要 JDK8,您可以从此处下载。

这个 ConcurrentEventMap 更像是一个临时的组合。我正在努力使用 ScalaSTM 获得更好的实现(请参阅http://nbronson.github.io/scala-stm/)。这也可能是您的一个选择。

于 2013-05-14T11:19:26.467 回答