如果我有这个同步代码,我想用没有同步的演员替换它,怎么办?
public synchronized int incrementAndGet() {
i = i + 1;
return i;
}
我在网站上有一群用户,我需要为每个用户返回一个递增的数字......我如何用没有同步的演员代码替换该代码,因此没有阻塞同步代码。我猜这将能够在多核等上运行它(这不是演员的目的吗?)。
如果我有这个同步代码,我想用没有同步的演员替换它,怎么办?
public synchronized int incrementAndGet() {
i = i + 1;
return i;
}
我在网站上有一群用户,我需要为每个用户返回一个递增的数字......我如何用没有同步的演员代码替换该代码,因此没有阻塞同步代码。我猜这将能够在多核等上运行它(这不是演员的目的吗?)。
一个简单的actor包裹i
在它的内部状态中:
case object Inc
class IncrementingActor extends Actor {
var i = 0
protected def receive = {
case Inc =>
i += 1
sender ! i
}
}
并阻止使用(您需要以incrementAndGet
某种方式获得):
import akka.pattern.ask
def incrementAndGet() =
Await.result((incrementingActor ? Inc).mapTo[Int], 1 seconds)
这段代码是:缓慢、复杂且不习惯。怎么样AtomicInteger
?
并发是一个具有多个问题和陷阱的广阔领域。没有一种方法能够解决所有问题,真正的并发专家能够结合多种方法来获得最佳结果。
目前在 JVM 世界中,我认为没有比原子整数更好的替代方法来增加计数器,尤其是在争用非常高的情况下。
话虽如此,如果你想使用actors,获得性能和可伸缩性的诀窍是尽可能避免ask ( ?
) 操作。改用tell ( !
) 然后yield。当结果可用时,actor 将接收它并恢复控制。没有任何阻塞,线程池同时能够处理其他参与者。只有当你们中的大多数代码都在演员内部时,这才有效。
从 Thomas 解决方案开始,您可以编写如下内容:
case object Inc
case class Count(i)
class IncrementingActor extends Actor {
var i = 0
protected def receive = {
case Inc =>
i += 1
sender ! Count(i)
}
}
class FooActor( counter: ActorRef ) extends Actor {
protected def receive = {
case DoSomething() => {
// Perform some work
counter ! Inc
}
case Count(i) => {
// Do something with the counter result
}
}
}
incrementAndGet()
如果您想使用一个演员,同步递增一个计数器(如)几乎没有什么好处。从视图中隐藏,实际上演员的邮箱中存在同步。此外,AtomicInteger类在多核架构上也能正常工作。