Scala 未来超时奇怪的行为
scala future timeout strange behaviour
这里是示例代码 scala 2.13.3:
import scala.concurrent.{ExecutionContext}
val scheduller: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
val promise = Promise[A]()
scheduller.schedule(
new Runnable {
override def run(): Unit = {
promise.failure(new TimeoutException)
scheduller.shutdown()
}
},
500,
TimeUnit.MILLISECONDS
)
Future.firstCompletedOf(Seq(INF_FUTURE, promise.future))
如果 INF_FUTURE = Future.never
超时将起作用,但如果 INF_FUTURE = Future {while (true) {}}
则执行不会停止
你能解释一下这是怎么回事吗?
因为你使用了singleThreadScheduledExecutor
。我假设您从 scheduller
:
创建了 ExecutionContext
val scheduller: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.fromExecutorService(scheduller)
val promise = Promise[Int]()
scheduller.schedule(
new Runnable {
override def run(): Unit = {
promise.failure(new TimeoutException)
scheduller.shutdown()
}
},
500,
TimeUnit.MILLISECONDS
)
如果您只使用一个执行程序创建执行上下文,您的程序将评估同步并冻结在 while (true)
循环中。
如果你切换到全局执行上下文,问题将被遗漏(如果你的机器有一个以上的核心):
implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global
在 Future.never
的情况下,如果您将像这样等待结果:
Await.result(Future.firstCompletedOf(Seq(INF_FUTURE, promise.future)).map {
x =>
println(x)
}, 10.seconds)
你会得到异常:
Exception in thread "main"
java.util.concurrent.RejectedExecutionException: Task
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@eb88a9df
rejected from
java.util.concurrent.ScheduledThreadPoolExecutor@e24c7ced[Shutting
down, pool size = 1, active threads = 1, queued tasks = 0, completed
tasks = 1]
这给你打电话是关于线程池大小的问题。
所以,你对 Future.never
没有任何问题,因为你没有等待它的结果。
这里是示例代码 scala 2.13.3:
import scala.concurrent.{ExecutionContext}
val scheduller: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
val promise = Promise[A]()
scheduller.schedule(
new Runnable {
override def run(): Unit = {
promise.failure(new TimeoutException)
scheduller.shutdown()
}
},
500,
TimeUnit.MILLISECONDS
)
Future.firstCompletedOf(Seq(INF_FUTURE, promise.future))
如果 INF_FUTURE = Future.never
超时将起作用,但如果 INF_FUTURE = Future {while (true) {}}
则执行不会停止
你能解释一下这是怎么回事吗?
因为你使用了singleThreadScheduledExecutor
。我假设您从 scheduller
:
ExecutionContext
val scheduller: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.fromExecutorService(scheduller)
val promise = Promise[Int]()
scheduller.schedule(
new Runnable {
override def run(): Unit = {
promise.failure(new TimeoutException)
scheduller.shutdown()
}
},
500,
TimeUnit.MILLISECONDS
)
如果您只使用一个执行程序创建执行上下文,您的程序将评估同步并冻结在 while (true)
循环中。
如果你切换到全局执行上下文,问题将被遗漏(如果你的机器有一个以上的核心):
implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global
在 Future.never
的情况下,如果您将像这样等待结果:
Await.result(Future.firstCompletedOf(Seq(INF_FUTURE, promise.future)).map {
x =>
println(x)
}, 10.seconds)
你会得到异常:
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@eb88a9df rejected from java.util.concurrent.ScheduledThreadPoolExecutor@e24c7ced[Shutting down, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 1]
这给你打电话是关于线程池大小的问题。
所以,你对 Future.never
没有任何问题,因为你没有等待它的结果。