简体   繁体   English

Scala未来超时奇怪的行为

[英]scala future timeout strange behaviour

Here is example code scala 2.13.3:这是示例代码 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))

the time out will work if INF_FUTURE = Future.never but execution will not stops if INF_FUTURE = Future {while (true) {}} Can you explane what is going on here?如果INF_FUTURE = Future.never则超时将起作用,但如果INF_FUTURE = Future {while (true) {}}你能解释这里发生了什么吗?

It is because you use singleThreadScheduledExecutor .这是因为您使用singleThreadScheduledExecutor I assume you creates ExecutionContext from scheduller :我假设您从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
)

If you create execution context only with one executor your program will evaluate synchronous and freeze inside while (true) loop.如果您仅使用一个执行程序创建执行上下文,您的程序将在while (true)循环内评估同步和冻结。

If you will switch to global Execution context the problem will be missed (if your machine has more then one core):如果您将切换到全局执行上下文,问题将被忽略(如果您的机器有多个内核):

implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global

in case of Future.never if you will wait for result like so:Future.never情况下,如果你会像这样等待结果:

Await.result(Future.firstCompletedOf(Seq(INF_FUTURE, promise.future)).map {
  x =>
    println(x)
}, 10.seconds)

you will get Exception:你会得到异常:

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]线程“main”中的异常 java.util.concurrent.RejectedExecutionException:任务 java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@eb88a9df 从 java.util.concurrent.ScheduledThreadPoolExecutor@e24c7ced[关闭,池大小 = 1,活动线程 = 1 拒绝, 排队任务 = 0, 已完成任务 = 1]

which call you about problem with thread pool size.这会告诉您线程池大小的问题。 So, you don't have any problem with Future.never because you didn't wait for it's result.所以,你对Future.never没有任何问题,因为你没有等待它的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM