终止Actor和ActorSystem后应用程序不退出

Vis*_*ohn 6 scala akka

我有一个主程序,它创建一个ActorSystem,一个Actor并向actor发送一些消息.处理完消息后,我发送了PoisonPill来杀死Actor.然后我关闭了演员系统.

在演员中,我呼叫Await等待未来完成.我面临的问题是,即使演员被PoisonPill终止并且ActorSystem被关闭,应用程序也不会退出.

def main(args: Array[String]): Unit = {

    val actorSystem = ActorSystem("sytem")
    val creationActor = actorSystem.actorOf(Props[MyActor], "MyActor")
    ...
    creationActor ! Message    //may be called multiple times
    creationActor ! PoisonPill
    ...
}
Run Code Online (Sandbox Code Playgroud)

而Actor代码是

class MyActor extends Actor {

  override def receive: Receive = {
    case Message => {
       ...
      Await.result(Dataset.create(datasetId), 30 seconds) 
      //Dataset.create returns a Future. Also this method uses an
      //ExecutionContext of its own.
      ...
    }
  }

  override def postStop() = {
    context.system.shutdown()
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我注释掉Await.result部分,该程序将退出.

编辑:
看起来我找到了根本原因.

Dataset.create(...)中使用的ExecutionContext是罪魁祸首.当我使用不使用Futures的同步版本的Dataset.create(...)时,我的应用程序退出.

Dataset.create()使用的ec是这样定义的
implicit val defaultContext = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(100))

仍然很想知道为什么异步版本不会退出应用程序.

编辑2: 如果我将Await部分更改为

val future = BQDataset.create(datasetId)
future onComplete {
  case Success(d) => ...
  case Failure(e) => ...
}
Run Code Online (Sandbox Code Playgroud)

我还是面临同样的问题.正如@ cem-catikkas所提到的,在我调用时创建的ExecutionContext BQDataset.create正在徘徊.我通过使用jstack验证了这一点,并且可以看到"pool-1-thread-1" prio=5 tid=0x00007ff49aa1e800 nid=0x4e03 waiting

Vis*_*ohn 3

当我调用 时Dataset.create(\xe2\x80\xa6),该方法创建ExecutionContext并使用它来执行第三方库。该第三方库打开网络连接,并且没有适当的方法shutdown()close()方法来清理底层连接。

\n\n

因此,即使我调用ExecutionContext.shutdown(),它也无法关闭线程池。这就是应用程序没有退出的原因。

\n