線程、多線程與線程池總結(jié)

先看幾個概念:線程:進(jìn)程中負(fù)責(zé)程序執(zhí)行的執(zhí)行單元馒闷。一個進(jìn)程中至少有一個線程尚卫。多線程:解決多任務(wù)同時執(zhí)行的需求归榕,合理使用CPU資源。多線程的運(yùn)行是根據(jù)CPU切換完成吱涉,如何切換由CPU決定刹泄,因此多線程運(yùn)行具有不確定性外里。線程池:基本思想還是一種對象池的思想,開辟一塊內(nèi)存空間特石,里面存放了眾多(未死亡)的線程盅蝗,池中線程執(zhí)行調(diào)度由池管理器來處理。當(dāng)有線程任務(wù)時姆蘸,從池中取一個墩莫,執(zhí)行完成后線程對象歸池,這樣可以避免反復(fù)創(chuàng)建線程對象所帶來的性能開銷乞旦,節(jié)省了系統(tǒng)的資源贼穆。如果對線程概念不清晰的話,不妨先看看我是一個線程這篇文章兰粉,擬人化的故事闡述線程的工作原理故痊。
● 線程
創(chuàng)建線程的兩種方式:
一、繼承Thread類玖姑,擴(kuò)展線程愕秫。
class DemoThread extends Thread { @Override public void run() { super.run(); // Perform time-consuming operation... }}DemoThread t = new DemoThread();t.start();

繼承Thread類,覆蓋run()方法焰络。
創(chuàng)建線程對象并用start()方法啟動線程戴甩。

面試題
1)線程和進(jìn)程有什么區(qū)別?

一個進(jìn)程是一個獨(dú)立(self contained)的運(yùn)行環(huán)境闪彼,它可以被看作一個程序或者一個應(yīng)用甜孤。而線程是在進(jìn)程中執(zhí)行的一個任務(wù)。線程是進(jìn)程的子集畏腕,一個進(jìn)程可以有很多線程缴川,每條線程并行執(zhí)行不同的任務(wù)。不同的進(jìn)程使用不同的內(nèi)存空間描馅,而所有的線程共享一片相同的內(nèi)存空間把夸。別把它和棧內(nèi)存搞混,每個線程都擁有單獨(dú)的棧內(nèi)存用來存儲本地數(shù)據(jù)铭污。
2)如何在Java中實(shí)現(xiàn)線程恋日?

創(chuàng)建線程有兩種方式:一、繼承 Thread 類嘹狞,擴(kuò)展線程岂膳。二、實(shí)現(xiàn) Runnable 接口磅网。
3)Thread 類中的 start() 和 run() 方法有什么區(qū)別谈截?

調(diào)用 start() 方法才會啟動新線程;如果直接調(diào)用 Thread 的 run() 方法,它的行為就會和普通的方法一樣傻盟;為了在新的線程中執(zhí)行我們的代碼,必須使用 Thread.start() 方法嫂丙。
擴(kuò)展
Android 系統(tǒng)接口 HandlerThread 繼承了 Thread娘赴,它是一個可以使用 Handler 的 Thread,一個具有消息循環(huán)的線程跟啤。run()方法中通過 Looper.prepare() 來創(chuàng)建消息隊列诽表,通過 Looper.loop() 來開啟消息循環(huán)∮绶剩可以在 run() 方法中執(zhí)行耗時的任務(wù)竿奏,而 HandlerThread 內(nèi)部創(chuàng)建了消息隊列外界需要通過 Handler 的方式來通知 HandlerThread 執(zhí)行一個具體任務(wù);HandlerThread 的 run() 方法是一個無限的循環(huán)腥放,可以通過它的 quite() 或 quitSafely() 方法來終止線程的執(zhí)行泛啸;
二、實(shí)現(xiàn)Runnable接口秃症。
public class DemoActivity extends BaseActivity implements Runnable { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Thread t = new Thread(this); t.start(); } @Override public void run() { }}

面試題
1)用 Runnable 還是 Thread 候址?

我們都知道可以通過繼承 Thread 類或者調(diào)用 Runnable 接口來實(shí)現(xiàn)線程,問題是种柑,創(chuàng)建線程哪種方式更好呢岗仑?什么情況下使用它?這個問題很容易回答聚请,如果你知道Java不支持類的多重繼承荠雕,但允許你調(diào)用多個接口。所以如果你要繼承其他類驶赏,當(dāng)然是調(diào)用Runnable接口更好了炸卑。
2)Runnable 和 Callable 有什么不同?

Runnable 和 Callable 都代表那些要在不同的線程中執(zhí)行的任務(wù)母市。Runnable 從 JDK1.0 開始就有了矾兜,Callable 是在 JDK1.5 增加的。它們的主要區(qū)別是 Callable 的 call() 方法可以返回值和拋出異常患久,而 Runnable 的 run() 方法沒有這些功能椅寺。Callable 可以返回裝載有計算結(jié)果的 Future 對象。
?注意:這面第二個面試題主要是為了引出下面的擴(kuò)展蒋失,原諒我這樣為難人的出場返帕。
擴(kuò)展
先看一下 Runnable 和 Callable 的源碼
public interface Runnable { public void run();}public interface Callable<V> { V call() throws Exception;}

可以得出:
1)Callable 接口下的方法是 call(),Runnable 接口的方法是 run()篙挽。2)Callable 的任務(wù)執(zhí)行后可返回值荆萤,而 Runnable 的任務(wù)是不能返回值的。3)call() 方法可以拋出異常,run()方法不可以的链韭。4)運(yùn)行 Callable 任務(wù)可以拿到一個 Future 對象偏竟,表示異步計算的結(jié)果。它提供了檢查計算是否完成的方法敞峭,以等待計算的完成踊谋,并檢索計算的結(jié)果。通過 Future 對象可以了解任務(wù)執(zhí)行情況旋讹,可取消任務(wù)的執(zhí)行殖蚕,還可獲取執(zhí)行結(jié)果。
但是沉迹,但是睦疫,凡事都有但是嘛…
單獨(dú)使用 Callable,無法在新線程中(new Thread(Runnable r))使用鞭呕,Thread 類只支持 Runnable蛤育。不過 Callable 可以使用 ExecutorService (又拋出一個概念,這個概念將在下面的線程池中說明)葫松。
上面又提到了 Future缨伊,看一下 Future 接口:
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}

Future 定義了5個方法:
1)boolean cancel(boolean mayInterruptIfRunning):試圖取消對此任務(wù)的執(zhí)行。如果任務(wù)已完成进宝、或已取消刻坊,或者由于某些其他原因而無法取消,則此嘗試將失敗党晋。當(dāng)調(diào)用 cancel() 時谭胚,如果調(diào)用成功,而此任務(wù)尚未啟動未玻,則此任務(wù)將永不運(yùn)行灾而。如果任務(wù)已經(jīng)啟動,則 mayInterruptIfRunning 參數(shù)確定是否應(yīng)該以試圖停止任務(wù)的方式來中斷執(zhí)行此任務(wù)的線程扳剿。此方法返回后旁趟,對 isDone() 的后續(xù)調(diào)用將始終返回 true。如果此方法返回 true庇绽,則對 isCancelled() 的后續(xù)調(diào)用將始終返回 true锡搜。2)boolean isCancelled():如果在任務(wù)正常完成前將其取消,則返回 true瞧掺。3)boolean isDone():如果任務(wù)已完成耕餐,則返回 true。 可能由于正常終止辟狈、異吵Φ蓿或取消而完成夏跷,在所有這些情況中,此方法都將返回 true明未。4)V get()throws InterruptedException,ExecutionException:如有必要槽华,等待計算完成,然后獲取其結(jié)果趟妥。5)V get(long timeout,TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException: 如有必要硼莽,最多等待為使計算完成所給定的時間之后,獲取其結(jié)果(如果結(jié)果可用)煮纵。
看來 Future 接口也不能用在線程中,那怎么用偏螺,誰實(shí)現(xiàn)了 Future 接口呢行疏?答:FutureTask。
public class FutureTask<V> implements RunnableFuture<V> { ...}public interface RunnableFuture<V> extends Runnable, Future<V> { void run();}

FutureTask 實(shí)現(xiàn)了 Runnable 和 Future套像,所以兼顧兩者優(yōu)點(diǎn)酿联,既可以在 Thread 中使用,又可以在 ExecutorService 中使用夺巩。
看完上面啰哩啰嗦的介紹后贞让,下面我們具體看一下具體使用的示例:
Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { return "個人博客:sunfusheng.com"; }};FutureTask<String> task = new FutureTask<String>(callable);Thread t = new Thread(task);t.start(); // 啟動線程task.cancel(true); // 取消線程

使用 FutureTask 的好處是 FutureTask 是為了彌補(bǔ) Thread 的不足而設(shè)計的,它可以讓程序員準(zhǔn)確地知道線程什么時候執(zhí)行完成并獲得到線程執(zhí)行完成后返回的結(jié)果柳譬。FutureTask 是一種可以取消的異步的計算任務(wù)喳张,它的計算是通過 Callable 實(shí)現(xiàn)的,它等價于可以攜帶結(jié)果的 Runnable美澳,并且有三個狀態(tài):等待销部、運(yùn)行和完成。完成包括所有計算以任意的方式結(jié)束制跟,包括正常結(jié)束舅桩、取消和異常。
查看具體操作代碼請參考 《個人學(xué)習(xí)項目DroidStudy》雨膨,感謝您的關(guān)注擂涛。
● 多線程
多線程的概念很好理解就是多條線程同時存在,但要用好多線程確不容易聊记,涉及到多線程間通信撒妈,多線程共用一個資源等諸多問題。
使用多線程的優(yōu)缺點(diǎn):優(yōu)點(diǎn):1)適當(dāng)?shù)奶岣叱绦虻膱?zhí)行效率(多個線程同時執(zhí)行)排监。2)適當(dāng)?shù)奶岣吡速Y源利用率(CPU踩身、內(nèi)存等)。缺點(diǎn):1)占用一定的內(nèi)存空間社露。2)線程越多CPU的調(diào)度開銷越大挟阻。3)程序的復(fù)雜度會上升。
對于多線程的示例代碼感興趣的可以自己寫Demo啦,去運(yùn)行體會附鸽,下面我主要列出一些多線程的技術(shù)點(diǎn)脱拼。
synchronized
同步塊大家都比較熟悉,通過 synchronized 關(guān)鍵字來實(shí)現(xiàn)坷备;所有加上 synchronized 的方法和塊語句熄浓,在多線程訪問的時候,同一時刻只能有一個線程能夠訪問省撑。
wait()赌蔑、notify()、notifyAll()
這三個方法是 java.lang.Object 的 final native 方法竟秫,任何繼承 java.lang.Object 的類都有這三個方法娃惯。它們是Java語言提供的實(shí)現(xiàn)線程間阻塞和控制進(jìn)程內(nèi)調(diào)度的底層機(jī)制,平時我們會很少用到的肥败。
wait():導(dǎo)致線程進(jìn)入等待狀態(tài)趾浅,直到它被其他線程通過notify()或者notifyAll喚醒,該方法只能在同步方法中調(diào)用馒稍。
notify():隨機(jī)選擇一個在該對象上調(diào)用wait方法的線程皿哨,解除其阻塞狀態(tài),該方法只能在同步方法或同步塊內(nèi)部調(diào)用纽谒。
notifyAll():解除所有那些在該對象上調(diào)用wait方法的線程的阻塞狀態(tài)证膨,同樣該方法只能在同步方法或同步塊內(nèi)部調(diào)用。
調(diào)用這三個方法中任意一個鼓黔,當(dāng)前線程必須是鎖的持有者椎例,如果不是會拋出一個 IllegalMonitorStateException 異常。
wait() 與 Thread.sleep(long time) 的區(qū)別
sleep():在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)请祖,該線程不丟失任何監(jiān)視器的所屬權(quán)订歪,sleep() 是 Thread 類專屬的靜態(tài)方法,針對一個特定的線程肆捕。wait() 方法使實(shí)體所處線程暫停執(zhí)行刷晋,從而使對象進(jìn)入等待狀態(tài),直到被 notify() 方法通知或者 wait() 的等待的時間到慎陵。sleep() 方法使持有的線程暫停運(yùn)行眼虱,從而使線程進(jìn)入休眠狀態(tài),直到用 interrupt 方法來打斷他的休眠或者 sleep 的休眠的時間到席纽。wait() 方法進(jìn)入等待狀態(tài)時會釋放同步鎖捏悬,而 sleep() 方法不會釋放同步鎖。所以润梯,當(dāng)一個線程無限 sleep 時又沒有任何人去 interrupt 它的時候过牙,程序就產(chǎn)生大麻煩了甥厦,notify() 是用來通知線程,但在 notify() 之前線程是需要獲得 lock 的寇钉。另個意思就是必須寫在 synchronized(lockobj) {…} 之中刀疙。wait() 也是這個樣子,一個線程需要釋放某個 lock扫倡,也是在其獲得 lock 情況下才能夠釋放谦秧,所以 wait() 也需要放在 synchronized(lockobj) {…} 之中。
volatile 關(guān)鍵字
volatile 是一個特殊的修飾符撵溃,只有成員變量才能使用它疚鲤。在Java并發(fā)程序缺少同步類的情況下,多線程對成員變量的操作對其它線程是透明的缘挑。volatile 變量可以保證下一個讀取操作會在前一個寫操作之后發(fā)生集歇。線程都會直接從內(nèi)存中讀取該變量并且不緩存它。這就確保了線程讀取到的變量是同內(nèi)存中是一致的卖哎。
ThreadLocal 變量
ThreadLocal 是Java里一種特殊的變量。每個線程都有一個 ThreadLocal 就是每個線程都擁有了自己獨(dú)立的一個變量删性,競爭條件被徹底消除了亏娜。如果為每個線程提供一個自己獨(dú)有的變量拷貝,將大大提高效率蹬挺。首先维贺,通過復(fù)用減少了代價高昂的對象的創(chuàng)建個數(shù)。其次巴帮,你在沒有使用高代價的同步或者不變性的情況下獲得了線程安全溯泣。
join() 方法
join() 方法定義在 Thread 類中,所以調(diào)用者必須是一個線程榕茧,join() 方法主要是讓調(diào)用該方法的 Thread 完成 run() 方法里面的東西后垃沦,再執(zhí)行 join() 方法后面的代碼,看下下面的”意思”代碼:
Thread t1 = new Thread(計數(shù)線程一); Thread t2 = new Thread(計數(shù)線程二); t1.start(); t1.join(); // 等待計數(shù)線程一執(zhí)行完成用押,再執(zhí)行計數(shù)線程二t2.start();

啟動 t1 后肢簿,調(diào)用了 join() 方法,直到 t1 的計數(shù)任務(wù)結(jié)束蜻拨,才輪到 t2 啟動池充,然后 t2 才開始計數(shù)任務(wù),兩個線程是按著嚴(yán)格的順序來執(zhí)行的缎讼。如果 t2 的執(zhí)行需要依賴于 t1 中的完整數(shù)據(jù)的時候收夸,這種方法就可以很好的確保兩個線程的同步性。
Thread.yield() 方法
Thread.sleep(long time):線程暫時終止執(zhí)行(睡眠)一定的時間血崭。 Thread.yield():線程放棄運(yùn)行卧惜,將CPU的控制權(quán)讓出厘灼。
這兩個方法都會將當(dāng)前運(yùn)行線程的CPU控制權(quán)讓出來,但 sleep() 方法在指定的睡眠時間內(nèi)一定不會再得到運(yùn)行機(jī)會序苏,直到它的睡眠時間完成手幢;而 yield() 方法讓出控制權(quán)后,還有可能馬上被系統(tǒng)的調(diào)度機(jī)制選中來運(yùn)行忱详,比如围来,執(zhí)行yield()方法的線程優(yōu)先級高于其他的線程,那么這個線程即使執(zhí)行了 yield() 方法也可能不能起到讓出CPU控制權(quán)的效果匈睁,因為它讓出控制權(quán)后监透,進(jìn)入排隊隊列,調(diào)度機(jī)制將從等待運(yùn)行的線程隊列中選出一個等級最高的線程來運(yùn)行航唆,那么它又(很可能)被選中來運(yùn)行胀蛮。
擴(kuò)展
線程調(diào)度策略
(1) 搶占式調(diào)度策略
Java運(yùn)行時系統(tǒng)的線程調(diào)度算法是搶占式的。Java運(yùn)行時系統(tǒng)支持一種簡單的固定優(yōu)先級的調(diào)度算法糯钙。如果一個優(yōu)先級比其他任何處于可運(yùn)行狀態(tài)的線程都高的線程進(jìn)入就緒狀態(tài)粪狼,那么運(yùn)行時系統(tǒng)就會選擇該線程運(yùn)行。新的優(yōu)先級較高的線程搶占了其他線程任岸。但是Java運(yùn)行時系統(tǒng)并不搶占同優(yōu)先級的線程再榄。換句話說,Java運(yùn)行時系統(tǒng)不是分時的享潜。然而困鸥,基于Java Thread類的實(shí)現(xiàn)系統(tǒng)可能是支持分時的,因此編寫代碼時不要依賴分時剑按。當(dāng)系統(tǒng)中的處于就緒狀態(tài)的線程都具有相同優(yōu)先級時疾就,線程調(diào)度程序采用一種簡單的、非搶占式的輪轉(zhuǎn)的調(diào)度順序艺蝴。
(2) 時間片輪轉(zhuǎn)調(diào)度策略
有些系統(tǒng)的線程調(diào)度采用時間片輪轉(zhuǎn)調(diào)度策略猬腰。這種調(diào)度策略是從所有處于就緒狀態(tài)的線程中選擇優(yōu)先級最高的線程分配一定的CPU時間運(yùn)行。該時間過后再選擇其他線程運(yùn)行猜敢。只有當(dāng)線程運(yùn)行結(jié)束漆诽、放棄(yield)CPU或由于某種原因進(jìn)入阻塞狀態(tài),低優(yōu)先級的線程才有機(jī)會執(zhí)行锣枝。如果有兩個優(yōu)先級相同的線程都在等待CPU厢拭,則調(diào)度程序以輪轉(zhuǎn)的方式選擇運(yùn)行的線程。
以上把這些技術(shù)點(diǎn)總結(jié)出來撇叁,后面我會把多線程這塊的示例代碼更新到 《個人學(xué)習(xí)項目DroidStudy》供鸠,感謝您的關(guān)注。
● 線程池
創(chuàng)建多個線程不光麻煩而且相對影響系統(tǒng)性能陨闹,接下來讓我看看使用線程池來操作多線程楞捂。我把自己的 《個人學(xué)習(xí)項目DroidStudy》 中線程池轉(zhuǎn)成一個 gif 效果圖薄坏,大家可以實(shí)際把玩下去感受線程池的原理,有興趣的同學(xué)也可以先 star 下寨闹,我會在接下來的幾個月把這個學(xué)習(xí)的Demo工程完善好胶坠。
[圖片上傳中。繁堡。沈善。(1)]
線程池的優(yōu)點(diǎn)
1)避免線程的創(chuàng)建和銷毀帶來的性能開銷。2)避免大量的線程間因互相搶占系統(tǒng)資源導(dǎo)致的阻塞現(xiàn)象椭蹄。3}能夠?qū)€程進(jìn)行簡單的管理并提供定時執(zhí)行闻牡、間隔執(zhí)行等功能。
再擼一擼概念
Java里面線程池的頂級接口是 Executor绳矩,不過真正的線程池接口是 ExecutorService罩润, ExecutorService 的默認(rèn)實(shí)現(xiàn)是 ThreadPoolExecutor;普通類 Executors 里面調(diào)用的就是 ThreadPoolExecutor翼馆。
照例看一下各個接口的源碼:
public interface Executor { void execute(Runnable command);}public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); ...}public class Executors { public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } ...}

下面我創(chuàng)建的一個線程池:
ExecutorService pool = Executors.newCachedThreadPool();

Executors 提供四種線程池:
1)newCachedThreadPool 是一個可根據(jù)需要創(chuàng)建新線程的線程池割以,但是在以前構(gòu)造的線程可用時將重用它們。對于執(zhí)行很多短期異步任務(wù)的程序而言应媚,這些線程池通逞狭ぃ可提高程序性能。調(diào)用 execute() 將重用以前構(gòu)造的線程(如果線程可用)珍特。如果現(xiàn)有線程沒有可用的祝峻,則創(chuàng)建一個新線程并添加到池中魔吐。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程扎筒。因此,長時間保持空閑的線程池不會使用任何資源酬姆。注意嗜桌,可以使用 ThreadPoolExecutor 構(gòu)造方法創(chuàng)建具有類似屬性但細(xì)節(jié)不同(例如超時參數(shù))的線程池。

2)newSingleThreadExecutor 創(chuàng)建是一個單線程池辞色,也就是該線程池只有一個線程在工作骨宠,所有的任務(wù)是串行執(zhí)行的,如果這個唯一的線程因為異常結(jié)束相满,那么會有一個新的線程來替代它层亿,此線程池保證所有任務(wù)的執(zhí)行順序按照任務(wù)的提交順序執(zhí)行。

3)newFixedThreadPool 創(chuàng)建固定大小的線程池立美,每次提交一個任務(wù)就創(chuàng)建一個線程匿又,直到線程達(dá)到線程池的最大大小,線程池的大小一旦達(dá)到最大值就會保持不變建蹄,如果某個線程因為執(zhí)行異常而結(jié)束碌更,那么線程池會補(bǔ)充一個新線程裕偿。

4)newScheduledThreadPool 創(chuàng)建一個大小無限的線程池,此線程池支持定時以及周期性執(zhí)行任務(wù)的需求痛单。

通過 ThreadPoolExecutor 的構(gòu)造函數(shù)嘿棘,擼一擼線程池相關(guān)參數(shù)的概念:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);}

1)corePoolSize:線程池的核心線程數(shù),一般情況下不管有沒有任務(wù)都會一直在線程池中一直存活旭绒,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 設(shè)置為 true 時鸟妙,閑置的核心線程會存在超時機(jī)制,如果在指定時間沒有新任務(wù)來時快压,核心線程也會被終止圆仔,而這個時間間隔由第3個屬性 keepAliveTime 指定。

2)maximumPoolSize:線程池所能容納的最大線程數(shù)蔫劣,當(dāng)活動的線程數(shù)達(dá)到這個值后坪郭,后續(xù)的新任務(wù)將會被阻塞。

3)keepAliveTime:控制線程閑置時的超時時長脉幢,超過則終止該線程歪沃。一般情況下用于非核心線程,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 設(shè)置為 true時嫌松,也作用于核心線程沪曙。

4)unit:用于指定 keepAliveTime 參數(shù)的時間單位,TimeUnit 是個 enum 枚舉類型萎羔,常用的有:TimeUnit.HOURS(小時)液走、TimeUnit.MINUTES(分鐘)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等贾陷。

5)workQueue:線程池的任務(wù)隊列缘眶,通過線程池的 execute(Runnable command) 方法會將任務(wù) Runnable 存儲在隊列中。

6)threadFactory:線程工廠髓废,它是一個接口巷懈,用來為線程池創(chuàng)建新線程的。

線程池的關(guān)閉
ThreadPoolExecutor 提供了兩個方法慌洪,用于線程池的關(guān)閉顶燕,分別是 shutdown() 和 shutdownNow()。
shutdown():不會立即的終止線程池冈爹,而是要等所有任務(wù)緩存隊列中的任務(wù)都執(zhí)行完后才終止涌攻,但再也不會接受新的任務(wù)。shutdownNow():立即終止線程池频伤,并嘗試打斷正在執(zhí)行的任務(wù)恳谎,并且清空任務(wù)緩存隊列,返回尚未執(zhí)行的任務(wù)剂买。
面試題
1)什么是 Executor 框架惠爽?
Executor框架在Java 5中被引入癌蓖,Executor 框架是一個根據(jù)一組執(zhí)行策略調(diào)用、調(diào)度婚肆、執(zhí)行和控制的異步任務(wù)的框架租副。
無限制的創(chuàng)建線程會引起應(yīng)用程序內(nèi)存溢出,所以創(chuàng)建一個線程池是個更好的的解決方案较性,因為可以限制線程的數(shù)量并且可以回收再利用這些線程用僧。利用 Executor 框架可以非常方便的創(chuàng)建一個線程池。
2)Executors 類是什么赞咙?
Executors為Executor责循、ExecutorService、ScheduledExecutorService攀操、ThreadFactory 和 Callable 類提供了一些工具方法院仿。Executors 可以用于方便的創(chuàng)建線程池。

轉(zhuǎn)自http://sunfusheng.com/java/2016/04/08/thread-threadpool.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末速和,一起剝皮案震驚了整個濱河市歹垫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颠放,老刑警劉巖排惨,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碰凶,居然都是意外死亡暮芭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門欲低,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辕宏,“玉大人,你說我怎么就攤上這事伸头∝倚В” “怎么了舷蟀?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵恤磷,是天一觀的道長。 經(jīng)常有香客問我野宜,道長扫步,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任匈子,我火速辦了婚禮河胎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虎敦。我一直安慰自己游岳,他們只是感情好政敢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胚迫,像睡著了一般喷户。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上访锻,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天褪尝,我揣著相機(jī)與錄音,去河邊找鬼期犬。 笑死河哑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的龟虎。 我是一名探鬼主播璃谨,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鲤妥!你這毒婦竟也來了睬罗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤旭斥,失蹤者是張志新(化名)和其女友劉穎容达,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垂券,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡花盐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了菇爪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片算芯。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖凳宙,靈堂內(nèi)的尸體忽然破棺而出熙揍,到底是詐尸還是另有隱情,我是刑警寧澤氏涩,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布届囚,位于F島的核電站,受9級特大地震影響是尖,放射性物質(zhì)發(fā)生泄漏意系。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一饺汹、第九天 我趴在偏房一處隱蔽的房頂上張望蛔添。 院中可真熱鬧,春花似錦、人聲如沸迎瞧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凶硅。三九已至蜘醋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咏尝,已是汗流浹背压语。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留编检,地道東北人胎食。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像允懂,于是被迫代替她去往敵國和親厕怜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容