5

如果我有这个同步代码,我想用没有同步的演员替换它,怎么办?

public synchronized int incrementAndGet() {
  i = i + 1;
  return i;
}

我在网站上有一群用户,我需要为每个用户返回一个递增的数字......我如何用没有同步的演员代码替换该代码,因此没有阻塞同步代码。我猜这将能够在多核等上运行它(这不是演员的目的吗?)。

4

3 回答 3

3

一个简单的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

于 2012-04-13T18:27:08.923 回答
3

并发是一个具有多个问题和陷阱的广阔领域。没有一种方法能够解决所有问题,真正的并发专家能够结合多种方法来获得最佳结果。

目前在 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   
    }
  }
}
于 2012-04-14T12:01:02.310 回答
0

incrementAndGet()如果您想使用一个演员,同步递增一个计数器(如)几乎没有什么好处。从视图中隐藏,实际上演员的邮箱中存在同步。此外,AtomicInteger类在多核架构上也能正常工作。

于 2012-04-28T00:27:49.563 回答