2013-09-10 2 views
27

Я учусь использовать exectorServices для пула threads и отправлю задачи. У меня есть простая программа подРазница между executor.submit и executor.execute в этом коде Java?

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 


class Processor implements Runnable { 

    private int id; 

    public Processor(int id) { 
     this.id = id; 
    } 

    public void run() { 
     System.out.println("Starting: " + id); 

     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      System.out.println("sorry, being interupted, good bye!"); 
      System.out.println("Interrupted "+Thread.currentThread().getName()); 
      e.printStackTrace();  
     } 

     System.out.println("Completed: " + id); 
    } 
} 


public class ExecutorExample { 

    public static void main(String[] args) { 
     Boolean isCompleted=false; 

     ExecutorService executor = Executors.newFixedThreadPool(2); 

     for(int i=0; i<5; i++) { 
      executor.execute(new Processor(i)); 
     } 

     //executor does not accept any more tasks but the submitted tasks continue 
     executor.shutdown(); 

     System.out.println("All tasks submitted."); 

     try { 
      //wait for the exectutor to terminate normally, which will return true 
      //if timeout happens, returns false, but this does NOT interrupt the threads 
      isCompleted=executor.awaitTermination(100, TimeUnit.SECONDS); 
      //this will interrupt thread it manages. catch the interrupted exception in the threads 
      //If not, threads will run forever and executor will never be able to shutdown. 
      executor.shutdownNow(); 
     } catch (InterruptedException e) { 
     } 

     if (isCompleted){ 
     System.out.println("All tasks completed."); 
     } 
     else { 
      System.out.println("Timeout "+Thread.currentThread().getName()); 
     } 
    } 
     } 

Он не делает ничего особенного, но создает два threads и представляет 5 заданий в общей сложности. После того, как каждый thread выполняет свою задачу, он берет следующую, В приведенном выше коде я использую executor.submit. Я также перешел на executor.execute. Но я не вижу никакой разницы в выходе. Каким образом различные методы submit and execute? Это то, что API говорит

Метод представить расширяет базовый метод Executor.execute (java.lang.Runnable) путем создания и возвращения будущего, который может быть использован для отмены выполнения и/или ждать завершения. Методы invokeAny и invokeAll выполняют наиболее часто используемые формы массового исполнения, выполняя набор задач, а затем ждут, по крайней мере, одного или всего. (Class ExecutorCompletionService можно использовать для написания индивидуальных вариантов этих методов.)

Но неясно ли это, что это значит? Благодаря

+0

полезный вопрос. Он имеет значение, чтобы опубликовать его здесь. – MKod

ответ

29

Как вы видите из JavaDoc execute(Runnable) ничего не возвращает.

Однако submit(Callable<T>) возвращает Future объект, который позволяет для вас способ отменить программно выполняемый поток позже, а также получить T, который возвращается, когда Callable не завершится. См JavaDoc of Future для более подробной информации

Future<?> future = executor.submit(longRunningJob); 
... 
//long running job is taking too long 
future.cancel(true); 

Кроме того, если future.get() == null и не выбрасывает никаких исключений, то Runnable успешно выполнен

30

Разница заключается в том, что execute просто запускает задачу без каких-либо дальнейших проволочек, в то время как submit возвращает Future объект для управления задачей. Вы можете выполнить следующие действия с Future объекта:

  • Отменить задачу досрочно, с помощью метода cancel.
  • Ждите выполнения задачи, начиная с get.

Интерфейс Future более полезен, если вы отправляете Callable в бассейн. Возвращаемое значение метода call будет возвращено при вызове Future.get. Если вы не поддерживаете ссылку на Future, нет никакой разницы.

3

Submit - Возвращает Future объект, который может быть использован для проверки результата, представленного задания. Может использоваться для отмены или проверки isDone и т. Д.

Выполнение - ничего не возвращает.

5

execute: Используйте его для огня и забыть звонки

submit: Используйте его, чтобы проверить результат вызова метода и принять соответствующие меры по Future возразили, возвращаемый вызовом

Основная разница: Exception обработки

submit() шкуры не обработаны Exception в рамках себя.

execute() броски не обработаны Exception.

Раствор для обработки исключений с submit()

  1. Оберните Callable or Runnable code in try{} catch{} block

    ИЛИ

  2. Держите future.get() call in try{} catch{} block

    ИЛИ

  3. реализовать свой собственный ThreadPoolExecutor и переопределить afterExecute метод

Что касается тура других запросов на

invokeAll:

Выполнение поставленных задач, возвращая список фьючерсов, затаив статус и результаты, когда все завершено или истекает время ожидания, в зависимости от того, что произойдет раньше.

invokeAny:

Выполнение поставленных задач, возвращая результат того, который завершился успешно (то есть, не выдавая исключение), если сделать до того, как данный тайм-аут истечет.

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

Используйте invokeAny, если вы ищете успешное завершение одной задачи из N отправленных задач. В этом случае выполняемые задачи будут отменены, если одна из задач завершится успешно.

Связанные пост с примером кода:

Choose between ExecutorService's submit and ExecutorService's execute

 Смежные вопросы

  • Нет связанных вопросов^_^