ExecutorService中submit()和execute()的區別


  在使用java.util.concurrent下關於線程池一些類的時候,相信很多人和我一樣,總是分不清submit()和execute()的區別,今天從源碼方面分析總結一下。

  通常,我們通過Executors這個工具類提供多種方法來創建適合不同場景的線程池,這里就不一一介紹了。

  例如,創建可緩存線程池,Executors.newCachedThreadPool(),源碼如下:

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

  通過上面源碼可以看出,該方法返回的是一個ExecutorService接口,而這個接口繼承Executor接口,Executor是最上層的,其中只包含一個execute()

方法:

public interface Executor {
    void execute(Runnable command);
}

  execute()方法的入參為一個Runnable,返回值為void,這時候我們已經知道了execute()方法的來源以及其定義。

  接下來,我們來看看,submit()是從哪來的呢?

  通過猜測,應該是ExecutorService接口中的,果然,打開源碼,看到了submit()方法:

public interface ExecutorService extends Executor {
  ...   
<T> Future<T> submit(Callable<T> task);   <T> Future<T> submit(Runnable task, T result);   Future<?> submit(Runnable task);
  ... }

  可以看出,在ExecutorService接口中,一共有以上三個sumbit()方法,入參可以為Callable<T>,也可以為Runnable,而且方法有返回值Future<T>

  (補充說明:Callable<T>與Runnable類似,也是創建線程的一種方式,實現其call()方法即可,方法可以有返回值,而且方法上可以拋出異常;)

  總結,從上面的源碼以及講解可以總結execute()和submit()方法的區別:

  1. 接收的參數不一樣;

  2. submit()有返回值,而execute()沒有;

    例如,有個validation的task,希望該task執行完后告訴我它的執行結果,是成功還是失敗,然后繼續下面的操作。

  3. submit()可以進行Exception處理;

    例如,如果task里會拋出checked或者unchecked exception,而你又希望外面的調用者能夠感知這些exception並做出及時的處理,那么就需要用到submit,通過對Future.get()進行拋出異常的捕獲,然后對其進行處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM