2013-07-22 4 views
4

Где я должен улавливать RejectedExecutionExceptions при выключении исполнителя? Я пробовал:Как поймать исключение ExjectException при использовании фьючерсов Scala?

future { 
     Option(reader.readLine) 
     } onComplete { 
     case Success(v) => 
     case Failure(e) => e match { 
      case ree: RejectedExecutionException => 
      // doesn't work 
     } 

и:

try { 
     future { 
      Option(reader.readLine) 
     } onComplete { 
      ... 
     } 
     } catch { 
     case ree: RejectedExecutionException => 
      // doesn't work 
     } 

также не работает. Все еще получение:

Exception in thread "pool-99-thread-1" java.util.concurrent.RejectedExecutionException 
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1768) 
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767) 
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658) 
at scala.concurrent.impl.ExecutionContextImpl.execute(ExecutionContextImpl.scala:105) 
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:37) 
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:133) 
at scala.concurrent.Promise$class.complete(Promise.scala:55) 
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:58) 
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
at java.lang.Thread.run(Thread.java:662) 

ответ

4

Должно быть обработано RejectedExecutionHandler. Либо java.util.concurrent.ThreadPoolExecutor.DiscardPolicy, либо вашей пользовательской реализацией.

Этот исполнитель молча проходит над RejectedExecutionException:

val executorService = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue[Runnable], Executors.defaultThreadFactory, new DiscardPolicy) 
2

Я спросил об этом in this thread.

Я чувствовал, что зарегистрированные обратные вызовы должны быть завершены при завершении работы, если они работают на одном и том же исполнителе. (Или поведение должно управляться политикой.) (Когда-нибудь я отправлю PR для того, что я описал, поскольку он кажется достаточно естественным.)

У меня была установка, в которой однопоточный исполнитель читает некоторые файлы и загруженные задания в другой пул. Первоначальная конструкция заключалась в том, что податчик подавлял себя, блокируя подачу. Это было хорошо, но негибко. Я хотел разворачивать некоторые задачи во втором пуле, но, конечно, подчинения будут блокироваться.

Итак, учитывая, что блокирование является злым, вы должны решить, что делать с вашими задачами, как только вы знаете, что не можете их запускать.

Один ответ заключается в том, что вы ожидаете покоя перед началом выключения. В моем случае у меня было количество заданий для завершения, поэтому я знал, когда работа была выполнена.

Точка зрения Виктора Клана в этой теме заключалась в том, что задачи разворачиваются и передаются все время, поэтому, если кто-то знает, что такое спокойствие, это приложение, а не инфраструктура.