首页 > 解决方案 > 在未来阻塞线程中休眠导致 RejectedExecutionException

问题描述

如果我这样做Thread.sleep,我会得到RejectedExecutionException,否则,代码可以正常工作。

是不是不能让线程休眠一段时间?

import java.util.concurrent.{Executors, TimeUnit}
import scala.concurrent.{ExecutionContext, Future, blocking}
import scala.util.{Failure, Success}

val executorService = Executors.newFixedThreadPool(2)
implicit val exec = ExecutionContext.fromExecutorService(executorService)

Future { blocking{
    println("Thread sleeps...")
    Thread.sleep(100)  // <<<< causes exception on 'shutdown'
    println("Thread running again...")
}} onComplete {
  case Success(_) => println("Done ABC")
  case Failure(exception) => println(exception)
}
exec.shutdown()
exec.awaitTermination(1000, TimeUnit.MILLISECONDS)

输出:

Thread sleeps...
Thread running again...
java.util.concurrent.RejectedExecutionException: Task scala.concurrent.impl.CallbackRunnable@79834f9b rejected from java.util.concurrent.ThreadPoolExecutor@35267234[Shutting down, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
    at scala.concurrent.impl.ExecutionContextImpl$$anon$1.execute(ExecutionContextImpl.scala:136)
    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:44)
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:252)
    at scala.concurrent.Promise$class.complete(Promise.scala:55)
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:157)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

标签: multithreadingscalathreadpoolexecutorservice

解决方案


通过删除onComplete,我看到没有例外。我已经使用 注册了一个回调onComplete但是该操作ExecutorService.shutdown一定不允许接受任何新任务。

如果未来已经完成,该功能应立即应用或异步调度。这不起作用,因为在我的情况下关闭了执行程序服务。


推荐阅读