留給開發者本身實現的接口,通常狀況下不須要再去實現。它只有一個方法 java
void execute(Runnable command)
它繼承自Executor接口,但多了以下3個功能 windows
1. <T> Future<T> submit(Callable<T> task) 2. Future<?> submit(Runnable task) 3. <T> Future<T> submit(Runnable task, T result)
Future<String> future = service.submit(task,"aaaa"); String s = future.get();// s="aaaa";
void submit(Runnable task)
這是由於Future除了get這種獲取任務信息外,還能夠控制任務,體如今 Future的這個方法上 性能優化
boolean cancel(boolean mayInterruptIfRunning)
這個方法的JavaDoc解釋的很清楚 性能
Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
注意:若是任務沒執行完,這3種方式的Future.get()都會阻塞。 fetch
boolean awaitTermination(long timeout,TimeUnit unit)
好比 優化
service.shutdown(); service.awaitTermination(20, TimeUnit.SECONDS);
它的意思是,當service.shutdown()後,主線程阻塞,任務執行結束或者阻塞20秒之後,阻塞解除。 ui
它繼承自ExecutorService接口。顧名思義,它主要用來按期執行任務或週期執行任務。它只有4個方法,都比較好理解。下面用最簡單的例子來作個說明 this
scheduler.schedule(callable,10,SECONDS); //10秒後開始執行callable任務 scheduler.schedule(runnable,10,Seconds); //10秒後開始執行runnable任務 scheduler.scheduleAtFixedRate(runnable, 5, 10, SECONDS); //5秒後開始執行Runnable任務,而後每隔10秒執行一遍該任務. scheduler.scheduleWithFixedDelay(runnable,5,10,SECONDS); //5秒後開始執行Runnable任務,而後任務執行完後再等10秒就執行一遍任務,即,每隔任務執行的時間+10秒再執行一遍任務。
這4個方法都返回ScheduledFuture對象.它繼承自Future接口,用途和Future差很少。 spa
在JDK以前,計劃任務通常由java.until.Timer類來完成。但相比起 ScheduleExecutorService來講,Timer類的功能較爲簡單,好比下例 線程
private final static long fONCE_PER_DAY = 1000*60*60*24; Timer timer = new Timer(); timer.scheduleAtFixedRate(fetchMail, getTomorrowMorning4am(), fONCE_PER_DAY);
這個類是一個工廠類,用來生成不一樣特色的ExecutorService或 ScheduledExecutorService實例。這裏主要介紹這些不一樣特色的實例不一樣在什麼地方。
static ExecutorService newSingleThreadExecutor()
啓動一個線程負責任務順序執行,順序意味着先提交的任務先執行。其原理是:任務會被提交到一個隊列裏,啓動的那個線程會從隊裏裏取任務,而後執行,執行完,再從隊列裏取下一個任務,再執行。若是該線程執行一個任務失敗,並致使線程結束,系統會建立一個新的線程去執行隊裏裏後續的任務,不會由於前面的任務有異常致使後面無辜的任務沒法執行。
static ExecutorService newCachedThreadPool()
啓動N個線程處理N個任務。既然是多個線程運行,意味着任務不會順序運行。一個任務完成後,該線程空閒60秒會被結束。新提交的任務會發現空閒線程,並使用它,若是沒有空閒線程可用則建立新線程。其實,這就是一個動態線程池。適合於規模比較小、建立較頻繁的任務。
static ExecutorService newFixedThreadPool(int nThreads)
動態線程池不限制線程的數量,在有些狀況下咱們不但願線程數量不可控,則可使用擁有固定線程數目的線程池。運做原理是:任務被提交到一個隊列裏排隊,線程池裏的空閒線程會把隊列裏的任務提出來執行,每一個線程執行完一個任務後,就去隊列裏抓另外一個任務出來執行。若是一個線程因爲失敗而終止,系統會建立另外一個線程執行後續任務。
//你本身的實現 class YourselfThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { Thread thread = new Thread(r); doXXX; return thread; } }
JavaDoc上說:Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
((ThreadPoolExecutor)newFixedThreadPool(1)).setCorePoolSize(3);
即newFixedThreadPool(1)能夠後期修改線程數,不能保證線程只有一個。而newSingleThreadExecutor能夠保證。
把Runnable任務轉換成Callable任務.例子以下
public static void test() throws Exception { Runnable task = new Runnable() { public void run() { log("begin task"); try { Thread.sleep(1000); } catch (InterruptedException e) { } log("end task"); } }; Callable c = Executors.callable(task); ExecutorService service = Executors.newCachedThreadPool(); Future f = service.submit(c); System.out.println(f.get());//返回null log("end"); } private static void log(String message) { System.out.println(new Date() + ": " + message); } public static void main(String args[]) throws Exception { test(); }