一:Runnable、Callable、FutureTask簡介
(1)Runnable:其中的run()方法沒有返回值。
①.Runnable對象可以直接扔給Thread創建線程實例,並且創建的線程實例與Runnable綁定,線程實例調用start()方法時,Runnable任務就開始真正在線程中執行。
②.Runnable對象也可以直接扔給線程池對象的execute方法和submit方法,讓線程池為其綁定池中的線程來執行。
③.Runnable對象也可以進一步封裝成FutureTask對象之后再扔給線程池的execute方法和submit方法。
(2)Callable:功能相比Runnable來說少很多,不能用來創建線程,也不能直接扔給線程池的execute方法,但是可以使用submit。其中的call方法有返回值,也進一步封裝成Future,再由線程執行。
(3)FutureTask:是對Runnable和Callable的進一步封裝,並且這種任務是有返回值的,它的返回值存在FutureTask類的一個名叫outcome的數據成員中。(疑惑)那么為什么可以把沒有返回值的Runnable也封裝成FutureTask呢,馬上我們會討論這個問題。相比直接把Runnable和Callable扔給線程池,FutureTask的功能更多,它可以監視任務在池子中的狀態。用Runnable和Callable創建FutureTask的方法稍有不同。
(4)Runable 轉換 Callable
Callable<Object> callable = Executors.callable(new MyRunnable());
(5)FutureTask 的使用
FutureTask futureTask = new FutureTask(new CallableTask());
new Thread(futureTask).start();//或者由線程池執行
FutureTask類實現了RunnableFuture接口,而RunnableFuture接口又繼承了Runnable接口和Future接口,所以FutureTask類本質上是Runnable接口的實現類,且兼具Future接口的特性,我們知道線程池的execute方法和submit方法都可以執行Runable任務,所以同樣可以執行FutureTask任務。
//FutureTask 構造函數
public FutureTask(Callable<V> callable);
public FutureTask(Runnable runnable, V result);
FutureTask類有一個done方法,該方法在任務執行完畢時自動回調,我們可以重寫該方法並在該方法中調用get()方法獲取任務執行的結果,並且因為任務已經執行完畢,此時調用get()方法可以直接得到結果,所以並不會阻塞線程。
二:線程池
(1)Executor 接口 只提供一個void execute(Runnable command),只能執行Runnable 任務,但是不能執行Callable 任務。所以提供了ExecutorService 接口。
(2)ExecutorService 接口 其繼承了Executor,提供了submit()方法重載可以執行Runnable 任務和Callable任務。ExecutorService 可以創建四種線程池
①newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); //返回ExecutorService
singleThreadExecutor .submit() //可以是Runable任務或者Callable任務
②newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); //返回ExecutorService
fixedThreadPool .submit();//可以是Runable任務或者Callable任務
③newCachedThreadPool創建一個可緩存線程池,如果處理需求超過線程池長度,可靈活回收空閑線程,若無可回收,則新建線程,線程池無限大,舉例:要執行兩個人,如果在第二個任務執行前,第一個任務已經完成,則會復用第一個線程去執行第二個任務,不創建新的線程。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); //返回ExecutorService
cachedThreadPool.submit();// 可以是Runable任務或者Callable任務
**④newScheduledThreadPool **創建一個定長線程池,支持定時及周期性任務執行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); //返回ScheduledExecutorService 其繼承了ExecutorService
scheduledThreadPool .scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
/*
ScheduledExecutorService接口 主要有以下方法,由ScheduledThreadPoolExecutor實現
1,<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) //執行Callable
2,ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) //執行Runable
3,ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) //以任務執行開始時間為起點,過多久執行一次
4,ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) //以任務執行結束時間為起點,過多久執行一次
*/
