2016-07-19 3 views
0

Если я использую Futures какИспользования shutdownNow в Параллельных рамках

List<Future<String>> results = executorService.invokeAll(tasks); 

или

Future<String> res = executorService.submit(new SingleWorker()); 
System.out.println(res.get()); 

системы ждет задач для завершения.

Даже если у меня было executorService.shutdownNow(); после упомянутых выше заявлений, я действительно не понимаю, когда система будет принудительно прекращать существующие потоки, как указано в документации, поскольку система никогда не достигает линии до завершения задач и возвращается будущее. Я что-то не хватает? Есть ли другой тестовый сценарий для его тестирования?

Will shutdownNow работают только с Runnable то есть когда мы говорим executorService.submit(new MyRunnable())?

EDIT:

Я пытался несколько различных вещей, и выяснили, что

а) shutdownNow не работает с invokeAll.

б) shutdownNow если они присутствуют после того, как Future.get тогда оператор shutdownNow заблокирован доFuture не будет решена (В случае Callable).

c) shutdownNow отлично работает с Runnable.

Ниже написано мой код для проверки:

class SingleRunnableWorker implements Runnable { 

    @Override 
    public void run() { 
     System.out.println("SingleRunnableWorker Running.."); 
     try { 
      Thread.sleep(10000); 
      System.out.println("SingleRunnableWorker Running after sleep.."); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

class SingleCallableWorker implements Callable<String> { 

    @Override 
    public String call() throws Exception { 
     System.out.println("SingleCallableWorker Calling.."); 
     Thread.sleep(10000); 
     System.out.println("SingleCallableWorker Calling after sleep.."); 
     return "SingleCallableWorker Calling done"; 
    } 

} 

и я тестирую его следующим образом:

ExecutorService executorService = Executors.newFixedThreadPool(4); 
/*List<Future<String>> results = */executorService.invokeAll(tasks);//blocks by default 

Future<String> res = executorService.submit(new SingleCallableWorker()); 
//System.out.println(res.get()); //blocks if uncommented 

executorService.submit(new SingleRunnableWorker()); 

executorService.shutdownNow(); 

, где задачи все Callables.

Нижняя линия: invokeAll и Future.get - блокирующие операции. Может кто-то пожалуйста подтвердите?

+2

'shutdownNow' попытается остановить потоки, выполняющие работу, которую вы отправляете соответствующему' ExecutorService'. Предположительно, существуют отдельные потоки, выполняющие 'Future # get()'. –

+1

"принудительно прекратить?" на самом деле, не прочитайте документ: «Нет никаких гарантий, кроме лучших попыток прекратить обработку, активно выполняющую задачи. Например, типичные реализации будут отменены с помощью Thread.interrupt(), поэтому любая задача, которая не отвечает на прерывания, может никогда не заканчиваться «. –

ответ

1

И Runnbale, и Callable вы отправили ThreadPoolExecutor, будут обернуты как java.util.concrrent.FutureTask и выполнены.

В этом случае, как в SingleRunnableWorker и SingleCallableWorker, когда задача блокируется Thread.sleep(10000), executorService.shutdownNow() заставит InterruptedException быть выброшены немедленно.

Но

  • InterruptedException выброшен в SingleRunnableWorker.run() является вынужден быть пойманной немедленно и обрабатываются e.printStackTrace().
  • InterruptedException выброшен в SingleCallableWorker.call() будет быть пойманной внутренним Syncronizer в FutureTask, то Syncronizer просто запись InterruptedException и возвращение. Когда вызывается future.get(), значение InterruptedException будет обернуто как ExecutionException и повторно выбрано.
Смежные вопросы