用线程代码替换标准同步的并行 Java "actor"代码是什么



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

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 世界中,我认为没有比原子整数更好的替代方案来增加计数器,尤其是在争用非常高的情况下。

话虽如此,如果你想使用Actor,获得性能和可伸缩性的诀窍是尽可能避免询问?)操作。改用告诉!),然后屈服。当结果可用时,参与者将收到它并恢复控制。没有阻塞,线程池能够同时照顾其他参与者。只有当大多数代码都在Actor内部时,这才有效。

从托马斯解决方案开始,你可以写这样的东西:

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   
    }
  }
}
如果要

使用Actor,同步递增计数器(如incrementAndGet())几乎没有什么好处。隐藏在视图中,实际上在执行组件的邮箱中存在同步。此外,AtomicInteger 类在多核体系结构上工作得很好。

最新更新