Thread類深度剖析-源碼學(xué)習(xí)

1 線程簡(jiǎn)介

首先我們要清楚的是,任何程序想要實(shí)現(xiàn)線程都需要內(nèi)核線程的支持,至少要有一個(gè),不然程序無法執(zhí)行。用戶線程和內(nèi)核線程的比例(M:N)體現(xiàn)了線程的不同實(shí)現(xiàn)方式。而對(duì)于高版本的Java(1.3及以后版本),一個(gè)Java的Thread就對(duì)應(yīng)一個(gè)操作系統(tǒng)的線程。

/**
 * 可以創(chuàng)建多個(gè)線程
 * <p>
 * 每個(gè)線程都有優(yōu)先級(jí)。
 * 指優(yōu)先級(jí)越高,越有可能先執(zhí)行。因?yàn)楦邇?yōu)先級(jí)的擁有更多資源,更容易搶到CPU資源而已。
 * 線程優(yōu)先級(jí)有繼承效果,比如main線程創(chuàng)建了線程A,則線程A初始優(yōu)先級(jí)繼承main的優(yōu)先級(jí),但是還可以修改為其他優(yōu)先級(jí)。
 * <p>
 * 線程分為用戶線程和守護(hù)線程。
 * 用戶線程執(zhí)行完之后,不管守護(hù)線程有沒有執(zhí)行完,jvm都會(huì)關(guān)閉
 * 守護(hù)線程A創(chuàng)建的線程B也是守護(hù)線程,但是守護(hù)線程B在未執(zhí)行之前可以設(shè)置為非守護(hù)線程
 * setDemon()方法當(dāng)線程開始之后就不可以設(shè)置了
 * if (isAlive()) {
 * throw new IllegalThreadStateException();
 * }
 * <p>
 * 創(chuàng)建線程 1 :繼承Thread類
 * 創(chuàng)建線程 2 :實(shí)現(xiàn)Runnable接口
 * 創(chuàng)建線程 1 :實(shí)現(xiàn)Callable<>接口 通過FuntureTask(Callable<> caller) 實(shí)現(xiàn),
 * 本質(zhì)上還是第二種方式,因?yàn)镕utureTask實(shí)現(xiàn)了 Runnable接口
 * <p>
 * The following code would then create a thread and start it running:
 * <blockquote><pre>
 *     PrimeRun p = new PrimeRun(143);
 *     new Thread(p).start();
 * </pre></blockquote>
 * <p>
 * 每個(gè)線程的名稱都是不同的,如果存在相同的線程名稱,會(huì)將設(shè)置相同名字的后一個(gè)線程重新生成名稱
 * <p>
 */
public class Thread implements Runnable {
/**
     * 初始化本地方法,(native方法) 當(dāng)執(zhí)行時(shí)不需要再去類庫(kù)加載,提升性能 靜態(tài)方法,類級(jí)別的
     * 可以理解成為本類的本地方法 提前注冊(cè)進(jìn)來 提升執(zhí)行時(shí)的性能
     * 都是靜態(tài)的,類裝載時(shí)執(zhí)行
     */
    private static native void registerNatives();

    static {
        registerNatives();
    }
}

2 線程上下文

CPU在一個(gè)時(shí)刻只能運(yùn)行一個(gè)線程,當(dāng)在運(yùn)行一個(gè)線程的過程中轉(zhuǎn)去運(yùn)行另外一個(gè)線程,這個(gè)叫做線程上下文切換(對(duì)于進(jìn)程也是類似)。

由于可能當(dāng)前線程的任務(wù)并沒有執(zhí)行完畢,所以在切換時(shí)需要保存線程的運(yùn)行狀態(tài),以便下次重新切換回來時(shí)能夠繼續(xù)切換之前的狀態(tài)運(yùn)行。舉個(gè)栗子:線程A正在讀取文件,當(dāng)讀到一半時(shí)需要暫停線程A,轉(zhuǎn)去執(zhí)行線程B,當(dāng)再次切換回來執(zhí)行線程A的時(shí)候,我們不希望線程A又從文件的開頭來讀取。因此需要記錄線程A的運(yùn)行狀態(tài)和執(zhí)行位置等,那么會(huì)記錄哪些數(shù)據(jù)呢?因?yàn)橄麓位謴?fù)時(shí)需要知道在這之前當(dāng)前線程已經(jīng)執(zhí)行到哪條指令了,所以需要記錄程序計(jì)數(shù)器的值,另外比如說線程正在進(jìn)行某個(gè)計(jì)算的時(shí)候被掛起了,那么下次繼續(xù)執(zhí)行的時(shí)候需要知道之前掛起時(shí)變量的值時(shí)多少,因此需要記錄CPU寄存器的狀態(tài)。所以一般來說,線程上下文切換過程中會(huì)記錄程序計(jì)數(shù)器、CPU寄存器狀態(tài)等數(shù)據(jù)。

對(duì)于線程的上下文切換實(shí)際上就是 存儲(chǔ)和恢復(fù)CPU狀態(tài)的過程,它使得線程執(zhí)行能夠從中斷點(diǎn)恢復(fù)執(zhí)行。

雖然多線程可以使得任務(wù)執(zhí)行的效率得到提升,但是由于在線程切換時(shí)同樣會(huì)帶來一定的開銷代價(jià),并且多個(gè)線程會(huì)導(dǎo)致系統(tǒng)資源占用的增加,所以在進(jìn)行多線程編程時(shí)要注意這些因素。

3 線程參數(shù)

private volatile String name; //線程名稱
private int priority; //線程優(yōu)先級(jí)
private Thread threadQ; //暫時(shí)不知道是干什么的,請(qǐng)教各位大佬 (感覺和JVM有關(guān))
private long eetop; //JVM中的JavaThread指針
private boolean single_step;//字面意思 是否單步執(zhí)行 請(qǐng)教各位大佬具體細(xì)節(jié)(感覺和JVM有關(guān))
private boolean daemon = false; //是否是守護(hù)線程,默認(rèn)false
private boolean stillborn = false; //字面意思 夭折 請(qǐng)教各位大佬具體細(xì)節(jié)(感覺和JVM state有關(guān))
private Runnable target; //指定運(yùn)行其中的Runnable,一般都需要指定,不指定的線程沒有意義,或者可以通過創(chuàng)建Thread的子類并重新run方法。
private ThreadGroup group; //指定當(dāng)前線程的線程組,未指定時(shí)線程組為創(chuàng)建該線程所屬的線程組。線程組可以用來管理一組線程,通過activeCount() 來查看活動(dòng)線程的數(shù)量。感覺除了這個(gè)沒有什么大的用處。如果有其他用處或理解歡迎留言
private ClassLoader contextClassLoader; //線程用的上下文類加載器,該上下文類加載器可供線程加載類和資源
private AccessControlContext inheritedAccessControlContext; //繼承的訪問系統(tǒng)資源的上下文(本線程的)
private static int threadInitNumber;//計(jì)數(shù)變量,用在nextThreadNum方法中為匿名線程生成名稱
ThreadLocal.ThreadLocalMap threadLocals = null; //線程局部變量
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; //可繼承的線程局部變量 比如一些 logId uid token 什么項(xiàng)目中共用的一些參數(shù)及標(biāo)準(zhǔn) 如果{true},則從構(gòu)造線程 繼承(inheritableThreadLocals) 的初始值 public的構(gòu)造器 此參數(shù)均為true
private long stackSize;// 新線程預(yù)期所需的堆棧大小,或者零表示該參數(shù)將被忽略。與平臺(tái)相關(guān),不建議使用該屬性。
private long nativeParkEventPointer;//native線程終止后,保持虛擬機(jī)私有狀態(tài)
private long tid;//線程id
private static long threadSeqNumber;//為了生成線程ID
private volatile int threadStatus = 0; // java線程狀態(tài),已初始化,0代表'not yet started'
volatile Object parkBlocker; //LockSupport.park是提供給當(dāng)前調(diào)用的參數(shù),由 LockSupport.setBlocker 設(shè)置,通過LockSupport.getBlocker訪問
private volatile Interruptible blocker;//此線程在 可中斷I/O操作中 被阻塞的對(duì)象(如果有)。設(shè)置此線程的中斷狀態(tài)后,應(yīng)調(diào)用 該對(duì)象的中斷方法。
private final Object blockerLock = new Object();

4 線程優(yōu)先級(jí)

1.java線程是通過映射到系統(tǒng)的原生線程上來實(shí)現(xiàn)的,所以線程的調(diào)度最終還是取決于操作系統(tǒng),操作系統(tǒng)的優(yōu)先級(jí)與java的優(yōu)先級(jí)并不一一對(duì)應(yīng),如果操作系統(tǒng)的優(yōu)先級(jí)級(jí)數(shù)大于java的優(yōu)先級(jí)級(jí)數(shù)(10級(jí))還好,但是如果小于得的話就不行了,這樣會(huì)導(dǎo)致不同優(yōu)先級(jí)的線程的優(yōu)先級(jí)是一樣的。
2.優(yōu)先級(jí)可能會(huì)被系統(tǒng)自動(dòng)改變,比如windows系統(tǒng)中就存在一個(gè)優(yōu)先級(jí)推進(jìn)器,大致功能就是如果一個(gè)線程執(zhí)行的次數(shù)過多的話,可能會(huì)越過優(yōu)先級(jí)為他分配執(zhí)行時(shí)間
3.線程的調(diào)度最終還是取決于操作系統(tǒng)中的線程規(guī)劃器。其實(shí),即使設(shè)置了線程的優(yōu)先級(jí),一樣無法確保這個(gè)線程一定先執(zhí)行,因?yàn)樗泻艽蟮碾S機(jī)性。它并無法控制執(zhí)行哪個(gè)線程,因?yàn)榫€程的執(zhí)行,是搶占資源后才能執(zhí)行的操作,而搶點(diǎn)資源時(shí),最多是給于線程優(yōu)先級(jí)較高的線程一點(diǎn)機(jī)會(huì)而已,能不能抓住可是不一定的。

說到底就一句話:線程優(yōu)化級(jí)較高的線程不一定先執(zhí)行。

5 線程狀態(tài)

線程狀態(tài)流轉(zhuǎn).png

線程內(nèi)部枚舉有6種狀態(tài):NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED

NEW:新生;尚未啟動(dòng)的線程的線程狀態(tài)

RUNNABLE:可運(yùn)行; 可運(yùn)行線程的線程狀態(tài)。
處于可運(yùn)行狀態(tài)的線程正在Java虛擬機(jī)中執(zhí)行,但可能需要等待其他資源調(diào)度,如CPU。

BLOCKED:阻塞;處于阻塞狀態(tài)的線程正在等待鎖。BLOCKED 狀態(tài)可以視作是一種特殊的 WAITING,特指等待鎖。

BLOCKED 源碼注釋:
1.一個(gè)處于 blocked 狀態(tài)的線程正在等待一個(gè)監(jiān)視器鎖以進(jìn)入一個(gè)同步的塊或方法。
A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or 
2.或在其調(diào)用 Object.wait 方法之后,以再次進(jìn)入一個(gè)同步的塊或方法。
reenter a synchronized block/method after calling Object.wait

第一句:本線程在等待其他線程釋放鎖,獲得鎖之后才能執(zhí)行后面鎖住的代碼塊或者方法。
第二句:本線程持有鎖,內(nèi)部調(diào)用 Object.wait 方法進(jìn)入阻塞狀態(tài),這時(shí)會(huì)釋放鎖,等待其他線程 Object.notify方法將本線程喚醒,喚醒后需要重新獲取到鎖才能繼續(xù)執(zhí)行后面的代碼塊??梢钥闯鲆韵聨c(diǎn):
1.必須持有該鎖才能調(diào)用該鎖的 wait 方法,這是第一次 enter。
2.調(diào)用 wait 之后線程會(huì)釋放該鎖,并進(jìn)入該鎖的等待隊(duì)列(wait set)中,狀態(tài)變?yōu)閃AITING。
3.當(dāng)收到其它線程對(duì)該鎖的 notify 或 notifyAll 通知之后,等待線程并不能立即恢復(fù)執(zhí)行,因?yàn)橥V沟牡胤绞窃谕綁K內(nèi),而鎖已經(jīng)釋放了,所以它要重新獲取鎖才能再次執(zhí)行后續(xù)的同步塊reenter。這是第二次 enter,所以叫 reenter。
4.但是該線程還是要與其它線程去競(jìng)爭(zhēng)鎖,這一過程跟 enter 的過程一樣,因此也會(huì)因?yàn)殒i已經(jīng)被其它線程據(jù)有而導(dǎo)致 BLOCKED。

WAITING:等待;一個(gè)正在無限期等待其他線程執(zhí)行完成處于這一狀態(tài),他和BLOCKED區(qū)別在于需不需要等待鎖。

TIMED_WAITING:持續(xù)時(shí)間等待,有限期的等待;

TERMINATED:結(jié)束。

6 線程方法

Thread Thread.currentThread() //獲得當(dāng)前線程的引用。
boolean isAlive() //測(cè)試線程是否處于活動(dòng)狀態(tài)。
void setDaemon(boolean on) //設(shè)置線程是否為守護(hù)線程
boolean isDaemon() //測(cè)試線程是否為守護(hù)線程。
void checkAccess() //判斷當(dāng)前運(yùn)行的線程是否有權(quán)修改該線程。
int Thread.activeCount()//當(dāng)前線程所在線程組中活動(dòng)線程的數(shù)目。
StackTraceElement[] getStackTrace() //獲取堆棧數(shù)組。
void dumpStack() //打印堆棧。
int enumerate(Thread[] tarray) //將當(dāng)前線程的線程組及其子組中的每一個(gè)活動(dòng)線程復(fù)制到指定的數(shù)組中。
Map<Thread,StackTraceElement[]> getAllStackTraces() //返回所有活動(dòng)線程的堆棧跟蹤的一個(gè)映射。
boolean holdsLock(Object obj) //當(dāng)且僅當(dāng)當(dāng)前線程在指定的對(duì)象上保持監(jiān)視器鎖時(shí),才返回 true。
void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) //設(shè)置由于未捕獲到異常導(dǎo)致線程終止時(shí)所調(diào)用的默認(rèn)處理程序。
Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() //返回線程由于未捕獲到異常而突然終止時(shí)調(diào)用的默認(rèn)處理程序。
Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() //返回該線程由于未捕獲到異常而突然終止時(shí)調(diào)用的處理程序。
void interrupt() //中斷線程。
boolean isInterrupted()//測(cè)試線程是否已經(jīng)中斷。
boolean interrupted() //測(cè)試當(dāng)前線程是否已經(jīng)中斷。
void sleep(long millis) //休眠指定時(shí)間
void sleep(long millis, int nanos) //休眠指定時(shí)間
void yield() //釋放cpu資源進(jìn)入就緒狀態(tài)重新爭(zhēng)搶資源。意義不太大
void join() //等待該線程終止。(內(nèi)部也依賴的wait方法)
void join(long millis) //等待該線程終止的時(shí)間最長(zhǎng)為 millis 毫秒。
void join(long millis, int nanos) //等待該線程終止的時(shí)間最長(zhǎng)為 millis 毫秒 + nanos 納秒。
void setContextClassLoader(ClassLoader cl) //設(shè)置該線程的上下文 ClassLoader。
void start()//使該線程開始執(zhí)行;Java 虛擬機(jī)調(diào)用該線程的 run 方法。
void run() //線程啟動(dòng)后執(zhí)行的方法。
比較重要的方法

/**
     * 使線程進(jìn)入就緒狀態(tài),等競(jìng)爭(zhēng)到CPU資源后執(zhí)行下面的run()方法
     *
     * @throws IllegalThreadStateException 線程啟動(dòng)后再次調(diào)用會(huì)報(bào)錯(cuò)
     */
    public synchronized void start() {
        /**
         * VM創(chuàng)建的線程或者系統(tǒng)線程組創(chuàng)建的線程 不是通過此方法創(chuàng)建的. 該方法邏輯可能會(huì)變化.
         */
        //0是就緒狀態(tài) 已經(jīng)是就緒狀態(tài),再調(diào)用此方法后就會(huì)報(bào)錯(cuò)
        if (threadStatus != 0) throw new IllegalThreadStateException();
        //通知線程組 該線程將要啟動(dòng)
        group.add(this);
        boolean started = false;
        try {
            //native方法,通過虛擬機(jī)啟動(dòng)線程
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                //什么也不做。防止覆蓋start0拋出的異常,讓該異常向上傳遞
            }
        }
    }
/**
     * 爭(zhēng)搶到CPU資源 線程真正執(zhí)行的方法
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

 /**
     * 中斷此線程.
     */
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }
/**
     * 測(cè)試當(dāng)前線程是否已被中斷。并且清除線程的 中斷狀態(tài)
     * 當(dāng)前線程已被中斷 返回true 并且清除線程的 中斷狀態(tài)(置為false)
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

    /**
     * 測(cè)試當(dāng)前線程是否已被中斷。 和上面方法差別是該方法 不清除線程的中斷狀態(tài)
     * 當(dāng)前線程已被中斷 返回true
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     * private 測(cè)試當(dāng)前線程是否已被中斷 根據(jù)參數(shù)看是否需要清楚中斷狀態(tài)
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

Thread.sleep(1000); 與 Thread.currentThread().sleep(1000); 等價(jià),都是在何處調(diào)用,就會(huì)使得當(dāng)前的線程進(jìn)入休眠狀態(tài), main線程調(diào)用threadB.sleep(1000)與調(diào)用Thread.sleep(1000)一樣,都是使main線程休眠1000毫秒,而不是使threadB休眠。
sleep方法不會(huì)釋放鎖。因?yàn)椴粡?qiáng)制需要鎖
sleep()支持中斷,因此當(dāng)檢測(cè)到中斷信號(hào)(isInterrupt=1)時(shí),會(huì)拋出InterruptedException 異常,因此在cache塊中可以對(duì)如果發(fā)生中斷進(jìn)行某些操作。通過isInterrupted()可以發(fā)現(xiàn):在拋出異常的時(shí)候,還讓異常狀態(tài)重新置為了false(isInterrupt=0)。
需要注意:由于不允許不同的線程之間的異常溢出,因此在run方法中就必須對(duì)此處拋出的InterruptedException異常進(jìn)行處理,因此上述示例代碼,直接對(duì)異常進(jìn)行了捕捉。若是在其他的普通方法中,除非是線程需要退出,否則都不應(yīng)當(dāng)直接將異常生吞。此時(shí)可以選擇:1.不捕捉 InterruptedException,將它傳播給調(diào)用者;2.捕捉InterruptedException執(zhí)行必要的清理操作,重新向上拋出InterruptedException異常;3.捕捉 InterruptedException 后重新恢復(fù)中斷狀態(tài)。

6 其他

創(chuàng)建線程:1Runnable接口,2.繼承Thread類,實(shí)際上也是實(shí)現(xiàn)Runnable接口,3.Callable/Future 4.線程池

實(shí)際應(yīng)用:

1、后臺(tái)任務(wù),例如:文件跑批,文件導(dǎo)出,定時(shí)百萬用戶推送消息;

2、異步處理,例如:多線程異步處理,提高程序響應(yīng);記錄日志;Tomcat內(nèi)部分發(fā)請(qǐng)求;BIO模型優(yōu)化:
Socket socket = socket.accept();//阻塞,連接阻塞
New Thread(new Handler(socket)).start();//解決了r/w阻塞問題

3、分布式計(jì)算

Thread類源碼

/**
 * 可以創(chuàng)建多個(gè)線程
 * <p>
 * 每個(gè)線程都有優(yōu)先級(jí)。
 * 指優(yōu)先級(jí)越高,越有可能先執(zhí)行。因?yàn)楦邇?yōu)先級(jí)的擁有更多資源,更容易搶到CPU資源而已。
 * 線程優(yōu)先級(jí)有繼承效果,比如main線程創(chuàng)建了線程A,則線程A初始優(yōu)先級(jí)繼承main的優(yōu)先級(jí),但是還可以修改為其他優(yōu)先級(jí)。
 * <p>
 * 線程分為用戶線程和守護(hù)線程。
 * 用戶線程執(zhí)行完之后,不管守護(hù)線程有沒有執(zhí)行完,jvm都會(huì)關(guān)閉
 * 守護(hù)線程A創(chuàng)建的線程B也是守護(hù)線程,但是守護(hù)線程B在未執(zhí)行之前可以設(shè)置為非守護(hù)線程
 * setDemon()方法當(dāng)線程開始之后就不可以設(shè)置了
 * if (isAlive()) {
 * throw new IllegalThreadStateException();
 * }
 * <p>
 * 創(chuàng)建線程 1 //繼承Thread類
 * 創(chuàng)建線程 2 //實(shí)現(xiàn)Runnable接口
 * 創(chuàng)建線程 1 //實(shí)現(xiàn)Callable<>接口 通過FuntureTask(Callable<> caller) 實(shí)現(xiàn),
 * 本質(zhì)上還是第二種方式,因?yàn)镕utureTask實(shí)現(xiàn)了 Runnable接口
 * <p>
 * The following code would then create a thread and start it running:
 * <blockquote><pre>
 *     PrimeRun p = new PrimeRun(143);
 *     new Thread(p).start();
 * </pre></blockquote>
 * <p>
 * 每個(gè)線程的名稱都是不同的,如果存在相同的線程名稱,會(huì)將設(shè)置相同名字的后一個(gè)線程重新生成名稱
 * <p>
 */
public class Thread implements Runnable {
    /**
     * 初始化本地方法,(native方法) 當(dāng)執(zhí)行時(shí)不需要再去類庫(kù)加載,提升性能 靜態(tài)方法,類級(jí)別的
     * 可以理解成為本類的本地方法 提前注冊(cè)進(jìn)來 提升執(zhí)行時(shí)的性能
     * 都是靜態(tài)的,類裝載時(shí)執(zhí)行
     */
    private static native void registerNatives();

    static {
        registerNatives();
    }

    private volatile String name; //線程名稱
    private int priority;         //線程優(yōu)先級(jí)
    private Thread threadQ;     //暫時(shí)不知道是干什么的,請(qǐng)教各位大佬 (感覺和JVM有關(guān))
    private long eetop; //JVM中的JavaThread指針
    private boolean single_step;//字面意思 是否單步執(zhí)行 請(qǐng)教各位大佬具體細(xì)節(jié)(感覺和JVM有關(guān))
    private boolean daemon = false; //是否是守護(hù)線程,默認(rèn)false
    private boolean stillborn = false; //字面意思 夭折 請(qǐng)教各位大佬具體細(xì)節(jié)(感覺和JVM state有關(guān))
    /**
     * 指定運(yùn)行其中的Runnable,一般都需要指定,不指定的線程沒有意義,或者可以通過創(chuàng)建Thread的子類并重新run方法。
     */
    private Runnable target;
    /**
     * 指定當(dāng)前線程的線程組,未指定時(shí)線程組為創(chuàng)建該線程所屬的線程組。
     * 線程組可以用來管理一組線程,通過activeCount() 來查看活動(dòng)線程的數(shù)量。感覺除了這個(gè)沒有什么大的用處。
     * 如果有其他用處或理解歡迎留言
     */
    private ThreadGroup group;
    /**
     * 線程用的上下文類加載器,該上下文類加載器可供線程加載類和資源
     */
    private ClassLoader contextClassLoader;
    /**
     * 繼承的訪問系統(tǒng)資源的上下文(本線程的)
     */
    private AccessControlContext inheritedAccessControlContext;
    /**
     * 計(jì)數(shù)變量,用在nextThreadNum方法中為匿名線程生成名稱
     */
    private static int threadInitNumber;

    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }

    /**
     * 線程局部變量
     */
    ThreadLocal.ThreadLocalMap threadLocals = null;
    /**
     * 可繼承的線程局部變量 比如一些 logId uid token 什么項(xiàng)目中共用的一些參數(shù)及標(biāo)準(zhǔn)
     * 如果{true},則從構(gòu)造線程 繼承 (inheritableThreadLocals) 的初始值
     * public的構(gòu)造器 此參數(shù)均為true
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
    /**
     * 新線程預(yù)期所需的堆棧大小,或者零表示該參數(shù)將被忽略。
     * 與平臺(tái)相關(guān),不建議使用該屬性。
     */
    private long stackSize;
    private long nativeParkEventPointer;//native線程終止后,保持虛擬機(jī)私有狀態(tài)
    private long tid;//線程id
    private static long threadSeqNumber;//為了生成線程ID
    /**
     * java線程狀態(tài),已初始化,0代表'not yet started'
     */
    private volatile int threadStatus = 0;

    private static synchronized long nextThreadID() {
        return ++threadSeqNumber;
    }

    /**
     * java.util.concurrent.locks.LockSupport.park.是提供給當(dāng)前調(diào)用的參數(shù)
     * 由 java.util.concurrent.locks.LockSupport.setBlocker 設(shè)置
     * 通過  java.util.concurrent.locks.LockSupport.getBlocker訪問
     */
    volatile Object parkBlocker;

    /**
     * 此線程在 可中斷I/O操作中 被阻塞的對(duì)象(如果有)。
     * 設(shè)置此線程的中斷狀態(tài)后,應(yīng)調(diào)用 該對(duì)象的中斷方法。
     */
    private volatile Interruptible blocker;
    private final Object blockerLock = new Object();

    /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
     */
    void blockedOn(Interruptible b) {
        synchronized (blockerLock) {
            blocker = b;
        }
    }

    public final static int MIN_PRIORITY = 1;
    public final static int NORM_PRIORITY = 5;
    public final static int MAX_PRIORITY = 10;

    /**
     * 返回 當(dāng)前正在執(zhí)行的線程
     */
    public static native Thread currentThread();

    /**
     * 向調(diào)度程序提示當(dāng)前線程愿意讓步,即讓出CPU資源和其他線程重新競(jìng)爭(zhēng)資源
     * 感覺沒什么用(主動(dòng)用的情況很少)
     */
    public static native void yield();

    /**
     * 使線程睡眠一段時(shí)間,線程掛起,讓出CPU資源
     * 不會(huì)釋放鎖,因?yàn)榇瞬僮鞑灰蕾嚰渔i (有鎖的話是使用者自己主觀意愿,所以需要使用者自己操作釋放鎖)
     *
     * @throws InterruptedException 睡眠中的線程被中斷會(huì)拋出該異常,該異常會(huì)清除中斷位的狀態(tài)
     */
    public static native void sleep(long millis) throws InterruptedException;

    public static void sleep(long millis, int nanos)
            throws InterruptedException {
        if (millis < 0) throw new IllegalArgumentException("timeout value is negative");
        if (nanos < 0 || nanos > 999999) throw new IllegalArgumentException("nanosecond timeout value out of range");
        if (nanos >= 500000 || (nanos != 0 && millis == 0)) millis++;
        sleep(millis);
    }

    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }

    /**
     * 使用當(dāng)前的AccessControlContext初始化線程。
     */
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) throw new NullPointerException("name cannot be null");
        this.name = name;
        Thread parent = currentThread();
        //獲取系統(tǒng)安全接口
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            //如果有系統(tǒng)安全manager,從manager中獲取當(dāng)前線程的線程組。
            if (security != null) g = security.getThreadGroup();
            //如果線程組為空,采用父類的線程組
            if (g == null) g = parent.getThreadGroup();
        }
        //校驗(yàn)是否可以訪問
        g.checkAccess();
        //校驗(yàn)是否允許
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        //增加線程組中未啟動(dòng)線程的數(shù)量。
        // 未啟動(dòng)的線程不會(huì)添加到線程組中,這樣即使從未啟動(dòng)過的線程也不會(huì)被收集,
        // 但是必須對(duì)它們進(jìn)行計(jì)數(shù),以便不會(huì)破壞其中未啟動(dòng)的線程的守護(hù)程序線程組。
        g.addUnstarted();
        //賦值
        this.group = g;
        //初始守護(hù)狀態(tài)繼承父類 后面可以主動(dòng)修改
        this.daemon = parent.isDaemon();
        //初始優(yōu)先級(jí)繼承父類 后面可以主動(dòng)修改
        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;
        //主動(dòng)修改 優(yōu)先級(jí)
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            //true時(shí)繼承父類 共用參數(shù)
            this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        this.stackSize = stackSize;
        //賦值tid
        tid = nextThreadID();
    }

    /**
     * 拋出CloneNotSupportedException,因?yàn)闊o法有意義地通過克隆構(gòu)造一個(gè)新的線程。
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
    }

    public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }

    public Thread(String name) {
        init(null, null, name, 0);
    }

    public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
    }

    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }

    public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }

    public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {
        init(group, target, name, stackSize);
    }

    /**
     * 使線程進(jìn)入就緒狀態(tài),等競(jìng)爭(zhēng)到CPU資源后執(zhí)行下面的run()方法
     *
     * @throws IllegalThreadStateException 線程啟動(dòng)后再次調(diào)用會(huì)報(bào)錯(cuò)
     */
    public synchronized void start() {
        /**
         * VM創(chuàng)建的線程或者系統(tǒng)線程組創(chuàng)建的線程 不是通過此方法創(chuàng)建的. 該方法邏輯可能會(huì)變化.
         */
        //0是就緒狀態(tài) 已經(jīng)是就緒狀態(tài),再調(diào)用此方法后就會(huì)報(bào)錯(cuò)
        if (threadStatus != 0) throw new IllegalThreadStateException();
        //通知線程組 該線程將要啟動(dòng)
        group.add(this);
        boolean started = false;
        try {
            //native方法,通過虛擬機(jī)啟動(dòng)線程
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                //什么也不做。防止覆蓋start0拋出的異常,讓該異常向上傳遞
            }
        }
    }

    private native void start0();

    /**
     * 爭(zhēng)搶到CPU資源 線程真正執(zhí)行的方法
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

    /**
     * 系統(tǒng)調(diào)用此方法,使線程有機(jī)會(huì)在線程實(shí)際退出之前進(jìn)行清理。
     */
    private void exit() {
        if (group != null) {
            group.threadTerminated(this);
            group = null;
        }
        target = null;
        threadLocals = null;
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }

    /**
     * 強(qiáng)制退出 (類比 kill -9) 過期方法 已經(jīng)不建議使用
     */
    @Deprecated
    public final void stop() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if (this != Thread.currentThread()) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // A zero status value corresponds to "NEW", it can't change to
        // not-NEW because we hold the lock.
        if (threadStatus != 0) {
            resume(); // Wake up thread if it was suspended; no-op otherwise
        }
        // The VM can handle all thread states
        stop0(new ThreadDeath());
    }

    @Deprecated
    public final synchronized void stop(Throwable obj) {
        throw new UnsupportedOperationException();
    }

    /**
     * 中斷此線程.
     */
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

    /**
     * 測(cè)試當(dāng)前線程是否已被中斷。并且清除線程的 中斷狀態(tài)
     * 當(dāng)前線程已被中斷 返回true 并且清除線程的 中斷狀態(tài)(置為false)
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

    /**
     * 測(cè)試當(dāng)前線程是否已被中斷。 和上面方法差別是該方法 不清除線程的中斷狀態(tài)
     * 當(dāng)前線程已被中斷 返回true
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     * private 測(cè)試當(dāng)前線程是否已被中斷 根據(jù)參數(shù)看是否需要清楚中斷狀態(tài)
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

    @Deprecated
    public void destroy() {
        throw new NoSuchMethodError();
    }

    /**
     * 測(cè)試線程是否存活
     */
    public final native boolean isAlive();

    /**
     * 掛起這個(gè)線程
     */
    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }

    /**
     * 恢復(fù)掛起的線程
     */
    @Deprecated
    public final void resume() {
        checkAccess();
        resume0();
    }

    /**
     * 設(shè)置線程優(yōu)先級(jí)
     */
    public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if ((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }

    /**
     * 獲取線程優(yōu)先級(jí)
     */
    public final int getPriority() {
        return priority;
    }

    public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }

    public final String getName() {
        return name;
    }

    public final ThreadGroup getThreadGroup() {
        return group;
    }

    /**
     * 返回線程組中活動(dòng)線程數(shù)的估計(jì)值 是估計(jì)值的原因是線程調(diào)用了start之后就算在估計(jì)值中 并不一定正在執(zhí)行
     */
    public static int activeCount() {
        return currentThread().getThreadGroup().activeCount();
    }

    /**
     * 將當(dāng)前線程的線程組及其子組中的每個(gè)活動(dòng)線程復(fù)制到指定的數(shù)組中
     */
    public static int enumerate(Thread tarray[]) {
        return currentThread().getThreadGroup().enumerate(tarray);
    }

    /**
     * 線程必須被掛起 然后計(jì)算此線程中的堆棧幀數(shù)并返回。
     */
    @Deprecated
    public native int countStackFrames();

    /**
     * 最多等待多少時(shí)間 使該線程結(jié)束
     */
    public final synchronized void join(long millis)
            throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

    public final synchronized void join(long millis, int nanos)
            throws InterruptedException {

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                    "nanosecond timeout value out of range");
        }
        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }
        join(millis);
    }

    /**
     * 等待線程執(zhí)行完
     */
    public final void join() throws InterruptedException {
        join(0);
    }

    public static void dumpStack() {
        new Exception("Stack trace").printStackTrace();
    }

    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }

    public final boolean isDaemon() {
        return daemon;
    }

    public final void checkAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkAccess(this);
        }
    }

    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                    group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                    "" + "]";
        }
    }

    @CallerSensitive
    public ClassLoader getContextClassLoader() {
        if (contextClassLoader == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(contextClassLoader,
                    Reflection.getCallerClass());
        }
        return contextClassLoader;
    }

    public void setContextClassLoader(ClassLoader cl) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
        }
        contextClassLoader = cl;
    }

    /**
     * 當(dāng)且僅當(dāng) 當(dāng)前線程 持有入?yún)㈡i時(shí),才返回 true
     */
    public static native boolean holdsLock(Object obj);

    private static final StackTraceElement[] EMPTY_STACK_TRACE
            = new StackTraceElement[0];

    public StackTraceElement[] getStackTrace() {
        if (this != Thread.currentThread()) {
            // check for getStackTrace permission
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkPermission(
                        SecurityConstants.GET_STACK_TRACE_PERMISSION);
            }
            // optimization so we do not call into the vm for threads that
            // have not yet started or have terminated
            if (!isAlive()) {
                return EMPTY_STACK_TRACE;
            }
            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[]{this});
            StackTraceElement[] stackTrace = stackTraceArray[0];
            // a thread that was alive during the previous isAlive call may have
            // since terminated, therefore not having a stacktrace.
            if (stackTrace == null) {
                stackTrace = EMPTY_STACK_TRACE;
            }
            return stackTrace;
        } else {
            // Don't need JVM help for current thread
            return (new Exception()).getStackTrace();
        }
    }

    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
        // check for getStackTrace permission
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                    SecurityConstants.GET_STACK_TRACE_PERMISSION);
            security.checkPermission(
                    SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
        }

        // Get a snapshot of the list of all threads
        Thread[] threads = getThreads();
        StackTraceElement[][] traces = dumpThreads(threads);
        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
        for (int i = 0; i < threads.length; i++) {
            StackTraceElement[] stackTrace = traces[i];
            if (stackTrace != null) {
                m.put(threads[i], stackTrace);
            }
            // else terminated so we don't put it in the map
        }
        return m;
    }

    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
            new RuntimePermission("enableContextClassLoaderOverride");

    private static class Caches {
        static final ConcurrentMap<WeakClassKey, Boolean> subclassAudits =
                new ConcurrentHashMap<>();

        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
                new ReferenceQueue<>();
    }

    private static boolean isCCLOverridden(Class<?> cl) {
        if (cl == Thread.class)
            return false;

        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
        Boolean result = Caches.subclassAudits.get(key);
        if (result == null) {
            result = Boolean.valueOf(auditSubclass(cl));
            Caches.subclassAudits.putIfAbsent(key, result);
        }

        return result.booleanValue();
    }

    private static boolean auditSubclass(final Class<?> subcl) {
        Boolean result = AccessController.doPrivileged(
                new PrivilegedAction<Boolean>() {
                    public Boolean run() {
                        for (Class<?> cl = subcl;
                             cl != Thread.class;
                             cl = cl.getSuperclass()) {
                            try {
                                cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
                                return Boolean.TRUE;
                            } catch (NoSuchMethodException ex) {
                            }
                            try {
                                Class<?>[] params = {ClassLoader.class};
                                cl.getDeclaredMethod("setContextClassLoader", params);
                                return Boolean.TRUE;
                            } catch (NoSuchMethodException ex) {
                            }
                        }
                        return Boolean.FALSE;
                    }
                }
        );
        return result.booleanValue();
    }

    private native static StackTraceElement[][] dumpThreads(Thread[] threads);

    private native static Thread[] getThreads();

    public long getId() {
        return tid;
    }

    /**
     * NEW:A thread that has not yet started is in this state.
     * RUNNABLE:A thread executing in the Java virtual machine is in this state.
     * BLOCKED:A thread that is blocked waiting for a monitor lock is in this state.
     * WAITING:A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
     * TIMED_WAITING:A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
     * TERMINATED:A thread that has exited is in this state.
     */
    public enum State {
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
        TIMED_WAITING,
        TERMINATED;
    }

    public State getState() {
        // get current thread state
        return sun.misc.VM.toThreadState(threadStatus);
    }

    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        /**
         * Method invoked when the given thread terminates due to the
         * given uncaught exception.
         * <p>Any exception thrown by this method will be ignored by the
         * Java Virtual Machine.
         *
         * @param t the thread
         * @param e the exception
         */
        void uncaughtException(Thread t, Throwable e);
    }

    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;

    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;

    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                    new RuntimePermission("setDefaultUncaughtExceptionHandler")
            );
        }

        defaultUncaughtExceptionHandler = eh;
    }

    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
        return defaultUncaughtExceptionHandler;
    }

    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
        return uncaughtExceptionHandler != null ?
                uncaughtExceptionHandler : group;
    }

    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        checkAccess();
        uncaughtExceptionHandler = eh;
    }

    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }

    static void processQueue(ReferenceQueue<Class<?>> queue,
                             ConcurrentMap<? extends
                                     WeakReference<Class<?>>, ?> map) {
        Reference<? extends Class<?>> ref;
        while ((ref = queue.poll()) != null) {
            map.remove(ref);
        }
    }

    static class WeakClassKey extends WeakReference<Class<?>> {
        /**
         * saved value of the referent's identity hash code, to maintain
         * a consistent hash code after the referent has been cleared
         */
        private final int hash;

        /**
         * Create a new WeakClassKey to the given object, registered
         * with a queue.
         */
        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
            super(cl, refQueue);
            hash = System.identityHashCode(cl);
        }

        /**
         * Returns the identity hash code of the original referent.
         */
        @Override
        public int hashCode() {
            return hash;
        }

        /**
         * Returns true if the given object is this identical
         * WeakClassKey instance, or, if this object's referent has not
         * been cleared, if the given object is another WeakClassKey
         * instance with the identical non-null referent as this one.
         */
        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;

            if (obj instanceof WeakClassKey) {
                Object referent = get();
                return (referent != null) &&
                        (referent == ((WeakClassKey) obj).get());
            } else {
                return false;
            }
        }
    }


    @sun.misc.Contended("tlr")
    long threadLocalRandomSeed;

    @sun.misc.Contended("tlr")
    int threadLocalRandomProbe;

    @sun.misc.Contended("tlr")
    int threadLocalRandomSecondarySeed;

    private native void setPriority0(int newPriority);

    private native void stop0(Object o);

    private native void suspend0();

    private native void resume0();

    private native void interrupt0();

    private native void setNativeName(String name);
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容