Я пробовал что-то с Futures в Scala.
Для данного атрибута executeContext 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) Почему функция сбоя в преобразовании была выполнена главной
нить?
2) Так как весь execContext был заполнен, почему мы не получили исключение rejectedExecutionException?
Но, когда я попробовал следующий код в основном, он работал по-другому:
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
Может кто-нибудь объяснить мне разницу между этими двумя программами. Технически второй код имеет почти такую же реализацию метода преобразования (за исключением вещи Try). Но, тем не менее, он ведет себя иначе.
Пожалуйста, помогите мне с пониманием того, что мне не хватает?