簡單解析execute和submit有什么區(qū)別
1、execute 方法位于 java.util.concurrent.Executor 中
void execute(Runnable command);
2、execute 的具體實現(xiàn)
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); /* * Proceed in 3 steps: * * 1. If fewer than corePoolSize threads are running, try to * start a new thread with the given command as its first * task. The call to addWorker atomically checks runState and * workerCount, and so prevents false alarms that would add * threads when it shouldn't, by returning false. * * 2. If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since entry into this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are none. * * 3. If we cannot queue task, then we try to add a new * thread. If it fails, we know we are shut down or saturated * and so reject the task. */ int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
3、submit 方法位于 java.util.concurrent.AbstractExecutorService 中
/** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask; } /** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public <T> Future<T> submit(Runnable task, T result) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task, result); execute(ftask); return ftask; } /** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
4、submit 方式使用 Runnable 入?yún)r的具體實現(xiàn)
static final class RunnableAdapter<T> implements Callable<T> { final Runnable task; final T result; RunnableAdapter(Runnable task, T result) { this.task = task; this.result = result; } public T call() { task.run(); return result; } }
5、submit 方式使用 Callable 入?yún)r的具體實現(xiàn)
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable } //重寫run方法 public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
總結(jié):
1、根據(jù)源碼可以看到 execute 僅可以接受Runnable類型,而 submit 重載了三個方法,參數(shù)可以是 Runnable 類型、Runnable 類型+泛型T 、Callable 類型接口。
2、從上面源碼可以看出 submit 方法實際上如果用Runnable類型的接口可以有返回值,也可以沒有返回值。
3、傳遞Runnable類型接口加泛型T會被進一步封裝,在 Executors 這個類里面有個內(nèi)部類 RunnableAdapter 實現(xiàn)了 Callable 接口。
4、看submit方法可以看出,submit最終也是在調(diào)用 execute 方法,無論是 Runnable 還是 Callable 類型接口,都會被封裝成 FutureTask 繼續(xù)執(zhí)行。
5、如果使用submit方法提交,會進一步封裝成FutureTask,執(zhí)行execute方法,在FutureTask里面重寫的run方法里面調(diào)用 Callable 接口的call方法。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
計算Java數(shù)組長度函數(shù)的方法以及代碼分析
在本篇內(nèi)容里,小編給大家整理了關(guān)于計算Java數(shù)組長度函數(shù)的方法以及代碼分析內(nèi)容,有興趣的朋友么可以學(xué)習(xí)參考下。2022-11-11關(guān)于@EnableGlobalMethodSecurity注解的用法解讀
這篇文章主要介紹了關(guān)于@EnableGlobalMethodSecurity注解的用法解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03Java中基于maven實現(xiàn)zxing二維碼功能
這篇文章主要介紹了Java中基于maven實現(xiàn)zxing二維碼功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02Java 實現(xiàn)攔截器Interceptor的攔截功能方式
這篇文章主要介紹了Java 實現(xiàn)攔截器Interceptor的攔截功能方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10springboot如何獲取相對路徑文件夾下靜態(tài)資源的方法
這篇文章主要介紹了springboot如何獲取相對路徑文件夾下靜態(tài)資源的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05