1.執行緒狀態變遷
2.為什麼notify/notifyall/ wait要在同步方法或塊中執行
2.1在j**a中,所有物件都能夠被作為"監視器monitor"——指乙個擁有乙個獨佔鎖,乙個入口佇列和乙個等待佇列的實體entity。所有物件的非同步方法都能夠在任意時刻被任意執行緒呼叫,此時不需要考慮加鎖的問題。而對於物件的同步方法來說,在任意時刻有且僅有乙個擁有該物件獨佔鎖的執行緒能夠呼叫它們。
2.2wait/notify/notifyall作用
(1)當乙個執行緒正在某乙個物件的同步方法中執行時呼叫了這個物件的wait()方法,那麼這個執行緒將釋放該物件的獨佔鎖並被放入這個物件的等待佇列。注意,wait()方法強制當前執行緒釋放物件鎖。
(2)當某執行緒呼叫某物件的notify()或notifyall()方法時,任意乙個(對於notify())或者所有(對於notifyall())在該物件的等待佇列中的執行緒,將被轉移到該物件的入口佇列。接著這些佇列(譯者注:可能只有乙個)將競爭該物件的鎖,最終獲得鎖的執行緒繼續執行。如果沒有執行緒在該物件的等待佇列中等待獲得鎖,那麼notify()和notifyall()將不起任何作用。在呼叫物件的notify()和notifyall()方法之前,呼叫執行緒必須已經得到該物件的鎖。
參考:3.thread方法(yield/join/sleep/守護執行緒)
yield:暫停當前正在執行的執行緒物件,只會給相同或更高高優先順序執行,如果沒有,則自己繼續執行
join:a中呼叫b.join(),表示等b執行完才執行a;呼叫join前需呼叫start,使執行緒處於就緒狀態
守護執行緒:a中有執行緒b啟動,b設定守護為true,則b守護a,a結束後b也結束
4.多執行緒實現
4.1方式
(1)實現介面runnable
(2)繼承thread
(3)callable與futuretask包裝器實現
(4)執行緒池建立
參考:4.2區別
* 如何理解實現callable介面的方式建立多執行緒比實現runnable介面建立多執行緒方式強大?
* 1. call()可以有返回值的。
* 2. call()可以丟擲異常,被外面的操作捕獲,獲取異常的資訊
* 3. callable是支援泛型的
5.執行緒池
執行緒池介面介紹:
5.1自定義執行緒池
threadpoolexecutor類
【引數】
corepoolsize:執行緒池核心數大小
maximumpoolsize:最大可建立執行緒數
keepalivetime:超過核心數時起作用(當核心與最大執行緒數一樣時,該值無用)
unit:時間單位
workqueue:儲存等待完成的任務
threadfactory:建立執行緒(執行命令的執行緒工廠)
handler:拒絕處理任務的策略(可以對丟棄的任務進行記錄)----
【執行緒池中線程初始化:0;1;all】prestartallcorethreads()方法---預建立worker執行緒
【任務拒絕策略:】
threadpoolexecutor.abortpolicy:丟棄任務並丟擲rejectedexecutionexception異常。(預設)
threadpoolexecutor.discardpolicy:也是丟棄任務,但是不丟擲異常。
threadpoolexecutor.discardoldestpolicy:丟棄佇列最前面的任務,然後重新嘗試執行任務(重複此過程)
threadpoolexecutor.callerrunspolicy:由呼叫執行緒處理該任務
【執行緒池關閉:】
shutdown():不會立即終止執行緒池,而是要等所有任務快取佇列中的任務都執行完後才終止,但再也不會接受新的任務
shutdownnow():立即終止執行緒池,並嘗試打斷正在執行的任務,並且清空任務快取佇列,返回尚未執行的任務
【幾種執行緒池區別:】
executors.newfixedthreadpool(int); //定長
new threadpoolexecutor(nthreads, nthreads,0l, timeunit.milliseconds, new linkedblockingqueue());
executors.newsinglethreadexecutor(); //可設定,預設大小:integer.max_value
new threadpoolexecutor(1, 1,0l, timeunit.milliseconds, new linkedblockingqueue())
executors.newcachedthreadpool(); //定長:1
new threadpoolexecutor(0, integer.max_value,60l, timeunit.seconds, new synchronousqueue());
newscheduledthreadpool;//定長,週期,定時
【如何合理配置執行緒池大小:】
如果是cpu密集型任務,就需要盡量壓榨cpu,參考值可以設為 ncpu+1
如果是io密集型任務,參考值可以設定為2*ncpu
【基本方法】
1)submit的效果和execute是一樣的,只是execute沒有返回值,而submit有返回值。
2)執行緒池可以執行(callable與runnable執行緒)
3)invokeany、invokeall
invokeany取得第乙個方法的返回值,當第乙個任務結束後,會呼叫interrupt方法中斷其它任務。
invokeall等執行緒任務執行完畢後,取得全部任務的結果值。
【週期執行任務執行緒】
以newscheduledthreadpool為例:
scheduleatfixedrate:以上乙個任務開始時間計時,120秒過去後,上乙個任務是否執行完,如果執行完畢,則當前任務立即執行,如果上乙個任務未執行完,則需等上乙個任務執行完後立即執行。直至追上次數後,再週期執行。
schedulewithfixeddelay:以上乙個任務結束時開始計時,120秒過去後,立即執行。
【補充】
* 1.使用executors建立執行緒池,不推薦使用,建議使用threadpoolexecutor自定義構建
* 2.執行緒池可執行callable執行緒/執行緒集合,有返回值;thread可執行callable;
* 3.手動定義執行緒池(核心執行緒池數量a,最大執行緒池數量b,延遲消亡執行緒時間c,時間單位d,請求阻塞佇列e,建立wor**程工廠f,自定義拒絕策略g)
(1)自定義work工廠:
(2)自定義拒絕策略:
(3)執行緒變遷過程:逐個建立執行緒f,達到a後,仍有執行緒進入,放入e,e滿後,檢視執行緒數是否達到b,如果達到,後續任務根據g策略拒絕。如果有執行緒空閒c時間後,如果當前執行緒數大於a,則該執行緒銷毀。參考:
*4.執行緒間通訊方式:參考:
5.阻塞佇列:參考:
執行緒池的狀態
running 這是最正常的狀態,接受新的任務,處理等待佇列中的任務。執行緒池的初始化狀態是running。執行緒池被一旦被建立,就處於running狀態,並且執行緒池中的任務數為0。shutdown 不接受新的任務提交,但是會繼續處理等待佇列中的任務。呼叫執行緒池的shutdown 方法時,執行緒...
執行緒池狀態介紹
本文介紹執行緒池的5種狀態,也可從原始碼中查詢,見下圖。本文詳細介紹下這五種狀態。代表當前執行緒池可以接受新的任務進行執行,也可以去處理佇列中的任務 表示當前執行緒池不再接受新的任務,當時仍然可以處理佇列中的任務,待處理完成後,狀態會發生改變 表示當前執行緒既不接受新的任務也不處理佇列中的任務,同事...
執行緒池 關於執行緒池的五種狀態
在threadpoolexecutor類中定義了執行緒的五種狀態表示,通過atomicinteger 的高三位來表示執行緒的狀態 private static final int count bits integer.size 3 private static final int running 1...