Будущее. Трансформируй себя странно - PullRequest
0 голосов
/ 06 июня 2019

Я пробовал что-то с 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). Но, тем не менее, он ведет себя иначе.

Пожалуйста, помогите мне с пониманием того, что мне не хватает?

...