0

我正在ExecutionContext为我的基于期货的代码使用自定义,这样每当用户决定中断程序时,无论正在发生的任何并发活动都会在他们第一次尝试安排另一个Future要处理的活动时被中断,并且程序可以退出,而不是等待任何长时间运行的任务完成。

但是,Executor.shutdownNow调用会导致 ajava.lang.InterruptedException来自 first sleep(500),但它永远不会到达 the Await.resultand 因此也不会到达catchorfinally块;此外,该程序只是无限期挂起。

import scala.concurrent._
import scala.concurrent.forkjoin.ForkJoinPool

object test extends App {
  val executor = new ForkJoinPool
  implicit val execCtx: ExecutionContext = ExecutionContext.fromExecutor(executor)

  try {
    Await.result(
      for {
        _ <- future { blocking { println(1); Thread.sleep(500); println(2) } }
        _ = executor.shutdownNow
        _ <- future { blocking { println(3); Thread.sleep(500); println(4) } }
      } yield (),
      duration.Duration.Inf)
  } catch { case _: InterruptedException =>
    println("CATCH") // not reached
  } finally {
    println("FINAL") // not reached
    executor.shutdown
  }
}

runMain test运行时(如果重要,使用 SBT ),这是输出:

1
shutting down[error] (ForkJoinPool-1-worker-13) java.lang.InterruptedException: sleep interrupted
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(test.scala:20)
    at test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(test.scala:20)
    at test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(test.scala:20)
    at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
    at scala.concurrent.package$.blocking(package.scala:50)
    at test$$anonfun$1.apply$mcV$sp(test.scala:20)
    at test$$anonfun$1.apply(test.scala:20)
    at test$$anonfun$1.apply(test.scala:20)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

为什么会这样?

4

0 回答 0