Scala Akka-即使演员被杀死,线程数也不确定地增长

时间:2019-07-16 08:33:24

标签: scala akka actor executioncontext

我正在为每个工作单元创建一个演员。每个参与者都创建一个线程池。 工作完成后,它会向发件人发送消息,发件人将向儿童演员发送毒药

我注意到,即使子角色被“杀死”,jvm进程中的线程数仍在不确定地增长。

示例

class ParentActor (...) extends Actor {
 ....
 ....

 val childActor = props(...child actor props...)
 val resultFuture = childActor ? "do some work"
 ...
 resultFuture onComplete {
   ...
   childActor ! PoisonPill // "kill" the child actor
 }

class ChildActor(...) extends Actor {
  val executionContext: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
...

  receive {
    ...
    sender ! "done"
  }

  override def postStop() {
    println("post stop called") // the actor prints this
  }
}

该actor不应连同其线程一起被GCd吗?

1 个答案:

答案 0 :(得分:2)

线程池不会自动收集垃圾。请参阅Java ThreadPoolExecutor

文档

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ThreadPoolExecutor.html

  

在程序中不再引用且没有剩余线程的池可以被回收(回收垃圾),而无需显式关闭。

但是,由于您正在创建固定池,因此它永远不会“没有剩余线程”。因此,即使子actor已停止,它也永远不会被JVM收集。

您可以在postStop中实现清理方法,调用shutdownNow()。但是,正如Thilo所指出的那样,在子角色中管理线程池非常不可思议。您没有解释为什么要这样做,但是我会考虑让Akka管理您的线程。