2013-09-10 60 views
27

我正在學習使用exectorServices來合併threads併發出任務。下面我有在Java代碼中的executor.submit和executor.execute之間的區別?

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說什麼

方法提交通過創建並返回一個可用於取消執行和/或等待完成的Future擴展基方法Executor.execute(一個java.lang.Runnable)。方法invokeAny和invokeAll執行最常用的批量執行形式,執行一組任務,然後等待至少一個或全部完成。 (ExecutorCompletionService類可用來編寫這些方法的自定義變體)

但它不是很清楚,我是什麼確切含義? 感謝

+0

有用的問題。它在這裏發佈它很有價值。 – MKod

回答

29

正如您從JavaDoc execute(Runnable)所看到的,不會返回任何內容。

然而,submit(Callable<T>)返回Future對象,它允許您以編程方式取消正在運行的線程更高版本,以及獲得那就是當Callable完成返回T的方式。見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

如果您向池中提交Callable,則Future接口更有用。當您致電Future.get時,將返回call方法的返回值。如果您不保留對Future的引用,則沒有區別。

3

執行提交 - 返回Future對象,可以用來檢查提交的任務的結果。可用於取消或檢查isDone等。

執行 - 不返回任何內容。

5

execute:將其用於消防和忘記調用

submit:用它來檢查方法調用的結果並採取Future適當行動反對由呼叫

主要區別返回:Exception處理

submit()在框架本身隱藏未處理的Exception

​​拋出未處理Exception

解決方案處理異常與submit()

  1. 包裝你Callable or Runnable code in try{} catch{} block

    OR

  2. 保持future.get() call in try{} catch{} block

    OR

  3. 實現自己的ThreadPoolExecutor並覆蓋afterExecute方法

關於對

invokeAll遊覽其他查詢:

執行給定的任務,返回的Future列表保持自己的狀態和結果,當所有完成或超時到期,以先發生者爲準。

invokeAny

執行給定的任務,返回一個已成功完成(即未拋出異常)的結果,如果說之前給定超時時間的任何事情。

如果您想等待所有提交的任務完成,請使用invokeAll

如果您正在尋找成功完成N個提交任務中的一個任務,請使用invokeAny。在這種情況下,如果其中一個任務成功完成,正在進行的任務將被取消。

相關帖子與代碼示例:

Choose between ExecutorService's submit and ExecutorService's execute

相關問題