我在Scala的Future中尝试一些东西。
给定执行上下文execContext
,它是一个执行上下文,其下是一个最小线程= 2的动态线程池,最大线程= 2,队列大小= 1,并且中止策略为RejectedExecutionHandler和以下函数,
def getFuture(): Future[Unit] = {
Future{
Thread.sleep(1000000000)
}(execContext)
}
当我在主要方法中使用转换时,
def main(args: Array[String]): Unit = {
val task1 = getFuture()
val task2 = getFuture()
val task3 = getFuture()
val task4 = try {
getFuture()
} catch {
case e: Exception => e.printStackTrace()
Future.failed(e)
}
val task5 = task4.transform(res => {
println("Success")
},
{
println("Failed " + Thread.currentThread().getName)
throw new NullPointerException})(execContext)
println("Awaiting here")
Await.result(task5 , Duration.Inf)
}
我在输出控制台上看到以下内容(这是符号输出,并不完全是):
1) java.util.concurrent.RejectedExecutionException: Task scala.concurrent.impl.Future$PromiseCompletingRunnable@5c42d2b7 rejected from java.util.concurrent.ThreadPoolExecutor@625abb97[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
2) Prints "Failed main" (Apparently main thread executed that function)
3) Exception in thread "main" java.lang.NullPointerException (Remember, I am throwing NullPointerException in failure function of transform)
我在这里有两个问题:
1)为什么转换中的失败函数由main执行 线?
2)由于整个execContext已填满,为什么我们没有收到任何rejectedExecutionException?
但是,当我在main中尝试以下代码时,它的工作方式有所不同:
def main(args: Array[String]): Unit = {
val task1 = getFuture()
val task2 = getFuture()
val task3 = getFuture()
val task4 = try {
getFuture()
} catch {
case e: Exception => e.printStackTrace()
Future.failed(e)
}
val p = Promise[Unit]()
task4.onComplete {
case Success(r) => println("Success")
case Failure(t) => println("Failure " + Thread.currentThread().getName)
}(execContext)
val task5 = p.future
println("Awaiting here")
Await.result(task5 , Duration.Inf)
}
此处,输出为以下类型:
1) java.util.concurrent.RejectedExecutionException: Task scala.concurrent.impl.Future$PromiseCompletingRunnable@40f70521 rejected from java.util.concurrent.ThreadPoolExecutor@774698ab[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
2) prints "Awaiting here"
3) java.util.concurrent.RejectedExecutionException: Task scala.concurrent.impl.CallbackRunnable@7c541c15 rejected from java.util.concurrent.ThreadPoolExecutor@774698ab[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
And the program keeps on running forever
有人可以向我解释这两个程序之间的区别吗?从技术上讲,第二代码具有与transform方法几乎相同的实现(“ Try”除外)。但是,它的行为方式仍然不同。
请帮助我理解我,我想念什么?