Thread機(jī)制與源碼分析

線程定義

線程是現(xiàn)代操作系統(tǒng)調(diào)度的最小單元,一個(gè)進(jìn)程可以創(chuàng)建多個(gè)線程來提高系統(tǒng)的吞吐量和執(zhí)行效率。

:進(jìn)程是操作系統(tǒng)資源分配和調(diào)度的基本單位,它可以創(chuàng)建多個(gè)線程,進(jìn)程可創(chuàng)建的線程數(shù)量跟操作系統(tǒng)相關(guān)。

為什么要使用多線程?

  • 更多的處理器核心;
  • 更快的響應(yīng)時(shí)間;
  • 更好的編程模型:java提供了一套完整的jmm規(guī)則,屏蔽了底層的一些操作,開發(fā)人員只需要關(guān)注自己的業(yè)務(wù)邏輯即可。

線程的狀態(tài)

  • NEW:初始狀態(tài),線程被構(gòu)建,還未調(diào)用start()方法;
  • RUNNABLE:運(yùn)行狀態(tài),在java多線程模型中,就緒和運(yùn)行都是運(yùn)行狀態(tài);
  • BLOCKED:阻塞狀態(tài);
  • WAITING:等待狀態(tài),比如中斷,需要其他的線程來喚醒;
  • TIME_WAITING:超時(shí)等待,可以在指定的時(shí)間內(nèi)自行返回;
  • TERMINATED:終止?fàn)顟B(tài),線程執(zhí)行完畢。

Thread源碼分析

  • 構(gòu)造線程

構(gòu)造函數(shù):

//無參構(gòu)造方法
public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

//帶參構(gòu)造方法
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

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);
}

所有的構(gòu)造方法都調(diào)用了init這個(gè)方法,接下來我們就來詳細(xì)的看看init方法到底是怎么來初始化線程的。

初始化線程:

private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
    //參數(shù)校驗(yàn),線程name不能為null
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }
    this.name = name.toCharArray();
    //當(dāng)前線程就是該線程的父線程
    Thread parent = currentThread();
    //獲取系統(tǒng)的security
    SecurityManager security = System.getSecurityManager();
    if (g == null) {
        //security不為null時(shí),線程所在group為security的group
        if (security != null) {
            g = security.getThreadGroup();
        }
        //security為null時(shí),直接使用父線程的group
        if (g == null) {
            g = parent.getThreadGroup();
        }
    }
    g.checkAccess();

    //授權(quán)
    if (security != null) {
        if (isCCLOverridden(getClass())) {            security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
        }
    }
    g.addUnstarted();
    this.group = g;
    //將守護(hù)線程、優(yōu)先級(jí)等設(shè)置為父線程的對(duì)應(yīng)屬性
    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);
    if (parent.inheritableThreadLocals != null)
        //創(chuàng)建線程共享變量副本
        this.inheritableThreadLocals =         ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    this.stackSize = stackSize;
    //分配線程id
    tid = nextThreadID();
}

  • 啟動(dòng)線程
public synchronized void start() {
    //假若當(dāng)前線程初始化還未做好,不能start,0->NEW狀態(tài)
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    //通知group該線程即將啟動(dòng),group的未啟動(dòng)線程數(shù)量減1
    group.add(this);

    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            //啟動(dòng)不成功,group設(shè)置當(dāng)前線程啟動(dòng)失敗
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {

        }
    }
}

啟動(dòng)線程其實(shí)做了這么幾件事:

  1. 檢查線程是否初始化;
  2. 通知group,線程啟動(dòng);
  3. 調(diào)用native方法start0()啟動(dòng)線程,啟動(dòng)后執(zhí)行run()方法;
  4. 啟動(dòng)失敗容錯(cuò)處理。

  • 線程中斷
    中斷可以理解為一個(gè)標(biāo)識(shí)位的屬性,它標(biāo)識(shí)一個(gè)運(yùn)行中的線程是否被其他線程進(jìn)行了中斷操作。

中斷線程:

public void interrupt() {
    //中斷其他線程,需要先判斷當(dāng)前線程是否允許修改其他線程
    if (this != Thread.currentThread())
        checkAccess();
    //中斷該線程
    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0();//設(shè)置中斷標(biāo)識(shí)位
            b.interrupt(this);
            return;
        }
    }
    interrupt0();
}

查看當(dāng)前線程是否被中斷:

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

查看線程是否被中斷,已中斷返回false

public boolean isInterrupted() {
    return isInterrupted(false);
}

  • 線程的暫停、恢復(fù)和停止

: 這幾個(gè)操作都加有@Deprecated注解,不推薦程序員使用

暫停:

//可能會(huì)造成死鎖
@Deprecated
public final void suspend() {
    checkAccess();
    suspend0();
}

恢復(fù):

//可能會(huì)造成死鎖
@Deprecated
public final void resume() {
    checkAccess();
    resume0();
}

停止:

@Deprecated
public final synchronized void stop(Throwable obj) {
    if (obj == null)
        throw new NullPointerException();

    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        checkAccess();
        if ((this != Thread.currentThread()) ||
            (!(obj instanceof ThreadDeath))) {
            security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
        }
    }
    //線程還未初始化好,暫停該線程
    if (threadStatus != 0) {
        resume(); 
    }

    //jvm處理線程相關(guān)內(nèi)容
    stop0(obj);
}

  • 線程優(yōu)先級(jí)設(shè)置
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í)不能作為程序正確性的依賴,操作系統(tǒng)有線程優(yōu)先級(jí)的設(shè)定,不以程序設(shè)定的優(yōu)先級(jí)為準(zhǔn)!

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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