【问题标题】:Why akka actor is so different from thread为什么 akka 演员与线程如此不同
【发布时间】:2014-10-27 05:50:10
【问题描述】:

我有一个演员来控制 GUI。 为了保证即时响应(不卡在屏幕上),我为这个演员分配了一个 PinnedDispatcher。

val system = ActorSystem("sys1")
def createMonitor(clients:Seq[ActorRef],init_QPS:Int) = system.actorOf(Props( new MonitorGUI) ).withDispatcher("my-pinned-dispatcher"))

配置文件是这样的

my-pinned-dispatcher {
  executor = "thread-pool-executor"
  type = PinnedDispatcher
}

actor程序是这样的

class MonitorGUI() extends Actor {
  val rate = 1000 milliseconds
  val scheduler = context.system.scheduler
  def receive = {

    case GUIRefresh =>
      GUI.refresh()
    case StartMonitor =>
      scheduler.schedule( rate + (300 milliseconds), rate ,self, GUIRefresh )
  }
}

调度程序应该每秒调用一次“刷新”。 然而,当有很多其他参与者进行大量繁重的计算时(例如 98% 的 CPU),调度程序不能保证每秒“刷新”。例如 GUI 卡住 5 秒。 然而,纯线程程序比 actor 程序响应更快,如下所示:

new Thread(new Runnable {
  override def run(): Unit = {
    while (true){
      GUI.refresh
      Thread.sleep(1000)
    }
  }
}).start()

我想知道为什么线程和演员如此不同。因为这个actor应该有自己的线程。应该没有区别。

【问题讨论】:

    标签: multithreading scala akka


    【解决方案1】:

    Actor 不像线程那样可抢占;当一个actor开始处理一条消息时,它将继续处理直到它完成该消息,然后才能运行另一个actor。这是为了高吞吐量而做出的设计决策(它消除了上下文切换),但在编写 actor 代码时需要注意这一点。

    要么确保单个消息的处理运行时间不会超过您期望的延迟(也许通过将计算拆分为小单元并发送新消息以触发每个步骤),或者为您的计算使用单独的执行上下文/调度程序- 重型演员和你的延迟敏感演员。 (理想情况下,您可能希望确保两个上下文中的线程总数等于物理 CPU 内核的数量,以便两个上下文的线程都不会阻塞另一个)。

    【讨论】:

      猜你喜欢
      • 2016-04-28
      • 2018-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      相关资源
      最近更新 更多