Thread類原始碼分析

2021-08-28 16:17:00 字數 4560 閱讀 3918

thread狀態

thread內部有個state列舉,標示著執行緒的狀態。

public

enum state

構造方法

建構函式及其幾個相關的成員變數

/* 帶目標run物件. */

private runnable target;

/* 執行緒組 */

private threadgroup group;

/* 此執行緒的類載入器 */

private classloader contextclassloader;

/* 想要的棧大小,為0時此引數被忽略,且有vm不支援此引數 */

private

long stacksize;

/* 狀態標識,0代表新建未開始*/

private

volatile

int threadstatus =

0;

建構函式很多,最終都調init方法

/**

* initializes a thread.

** @param g 執行緒組

* @param target 要執行的帶run的目標物件

* @param name 執行緒名

* @param stacksize 新執行緒的棧大小,等於0時可忽略此引數

* @param acc 接入控制上下文

*/private

void

init

(threadgroup g, runnable target, string name,

long stacksize, accesscontrolcontext acc)

this

.name = name;

thread parent =

currentthread()

; securitymanager security = system.

getsecuritymanager()

;//獲取執行緒組

if(g == null)

/* 如果還沒拿到從當前執行緒拿*/

if(g == null)

}/* 檢查是否可獲取 */

g.checkaccess()

;//還是許可權控制檢查

if(security != null)

} g.

addunstarted()

;this

.group = g;

this

.daemon = parent.

isdaemon()

;this

.priority = parent.

getpriority()

;if(security == null ||

isccloverridden

(parent.

getclass()

))this

.contextclassloader = parent.

getcontextclassloader()

;else

this

.contextclassloader = parent.contextclassloader;

this

.inheritedaccesscontrolcontext =

acc != null ? acc : accesscontroller.

getcontext()

;this

.target = target;

setpriority

(priority)

;//從父執行緒繼承可繼承的threadlocal

if(parent.inheritablethreadlocals != null)

this

.inheritablethreadlocals =

threadlocal.

createinheritedmap

(parent.inheritablethreadlocals)

;this

.stacksize = stacksize;

/* 設定執行緒id */

tid =

nextthreadid()

;}

啟動start
/* 執行緒啟動方法 */

public

synchronized

void

start()

finally

}catch

(throwable ignore)}}

private

native

void

start0()

;

start0方法是native實現,在真正開始之前校驗了狀態,並接入threadgroup管理。真正的執行的是目標類的run方法

/* runnale 介面的方法*/

@override

public

void

run(

)}

join方法

舉例:t.join()方法阻塞呼叫此方法的執行緒(calling thread),直到執行緒t完成,此執行緒再繼續

*如果這個執行緒還活著就一直等待*

/public

final

void

join()

throws interruptedexception

/*如果這個執行緒還活著就一直等待millis時間*/

public

final

synchronized

void

join

(long millis)

throws interruptedexception

if(millis ==0)

}else

wait

(delay)

; now = system.

currenttimemillis()

- base;}}

}

它被synchronized標記,實現主要是自旋方法檢驗t執行緒是否活著,如果活著,則主線程(呼叫執行緒)wait釋放鎖,指導t執行緒結束。

interrupt方法

每個執行緒都有乙個與之相關聯的 boolean 屬性,用於表示執行緒的中斷狀態(interrupted status)。中斷狀態初始時為 false;當另乙個執行緒通過呼叫 thread.interrupt() 中斷乙個執行緒時,會出現以下兩種情況之一。如果那個執行緒在執行乙個低階可中斷阻塞方法,例如 thread.sleep()、 thread.join() 或 object.wait(),那麼它將取消阻塞並丟擲 interruptedexception。否則, interrupt() 只是設定執行緒的中斷狀態。 在被中斷執行緒中執行的**以後可以輪詢中斷狀態,看看它是否被請求停止正在做的事情。中斷狀態可以通過 thread.isinterrupted() 來讀取,並且可以通過乙個名為 thread.interrupted() 的操作讀取和清除。

public

void

interrupt()

}interrupt0()

;}//當前執行緒是否被中斷,並清空中斷狀態(連續兩次呼叫,第二次一定返回false)

public

static

boolean

interrupted()

//當前執行緒是否被中,根據true,false來是否重置中斷zhuangt

private

native

boolean

isinterrupted

(boolean clearinterrupted)

;//當前執行緒是否被中斷,不修改中斷狀態

public

boolean

isinterrupted()

中斷是一種協作機制。當乙個執行緒中斷另乙個執行緒時,被中斷的執行緒不一定要立即停止正在做的事情。相反,中斷是禮貌地請求另乙個執行緒在它願意並且方便的時候停止它正在做的事情。有些方法,例如 thread.sleep(),很認真地對待這樣的請求,但每個方法不是一定要對中斷作出響應。對於中斷請求,不阻塞但是仍然要花較長時間執行的方法可以輪詢中斷狀態,並在被中斷的時候提前返回。 您可以隨意忽略中斷請求,但是這樣做的話會影響響應。

中斷的協作特性所帶來的乙個好處是,它為安全地構造可取消活動提供更大的靈活性。我們很少希望乙個活動立即停止;如果活動在正在進行更新的時候被取消,那麼程式資料結構可能處於不一致狀態。中斷允許乙個可取消活動來清理正在進行的工作,恢復不變數,通知其他活動它要被取消,然後才終止。

總結wait()和notify/notifyall()方法

wait()方法

notify/notifyall()方法

sleep/yield/join方法

sleep

yield

join

關於interrupt()中斷函式

Thread 類的原始碼相關

注意 run 方法存在於thread類 和 runnable 介面中 理解以下三種情況 定義乙個類繼承 thread 類,並重新了覆寫 run 方法,原先的 run方法就被子類的 run 方法覆蓋掉了,thread 類run 方法中的 target.run 就不可能執行了,執行緒物件 start 是...

Thread原始碼 類結構及變數含義

環境 jdk1.8 thread類結構 public class thread implements runnable 可以看出 1.thread是基於runnable實現,實現了run方法 thread類變數 執行緒名稱,用volatitle修飾,保證其可見性 private volatile s...

Thread原始碼問題練習

public static void main string args start a 輸出的是 thread匿名子類的run方法 b thread中呼叫runnable介面覆寫的run方法的方法,被override了,使得thread的start方法轉而呼叫thread匿名內部類 子類 中覆寫的r...