并發(fā)系列之線程終止

倫敦政治經(jīng)濟學(xué)院(英國)校訓(xùn):“了解萬物發(fā)生之緣由?!?/em>


在實際工作中,當(dāng)看到代碼中有直接new使用線程的話,這是需要警惕的,你手動創(chuàng)建了線程,自然要管理線程的生命周期,這其中必然包含著線程的結(jié)束。這是一個容易被忽略的小點,也是面試中高頻點,更是實際工作中推薦使用線程池的方式管理線程的緣由。
線程終止有很多方式,這里會介紹工作中推薦使用的終止方式和廢棄的方式,以及廢棄的原因,了解了這些,才能更好地管理線程。

一 推薦方式

常用方式主要有設(shè)置退出標(biāo)識和設(shè)置中斷標(biāo)識,有時線程在sleep/join等阻塞的情況下無法根據(jù)退出標(biāo)識進行終止的,這時就需要利用線程的中斷機制來優(yōu)雅地終止線程。具體看下演示demo:

/**
 * @author 阿倫故事
 * @Description:
 *  描述線程安全終止的方式
 *  1 設(shè)置exit標(biāo)識
 *  2 設(shè)置中斷標(biāo)識
 * */
@Slf4j
public class ThreadStop {

    //聲明內(nèi)存可見性全局變量
    private volatile boolean flag = false;

    public static void main(String[] args) throws Exception{
        ThreadStop threadStop = new ThreadStop();
        //設(shè)置exit標(biāo)識
        //threadStop.terminByExit();
        //設(shè)置中斷標(biāo)識
        threadStop.terminByInter();
    }
    /**
     * way1 :
     *      設(shè)置exit標(biāo)識
     * */
    public void terminByExit() throws InterruptedException {
        ThreadExit threadExit = new ThreadExit();
        log.info("--開啟子線程--");
        threadExit.start();
        Thread.currentThread().sleep(2000);
        flag = true;
        threadExit.join();
        log.info("--stop the world--");
    }
    public class ThreadExit extends Thread{
        @Override
        public void run(){
            while(!flag);
            log.info("--子線程執(zhí)行完畢--");
        }
    }
    /**
     * way2 :
     *      設(shè)置中斷標(biāo)識
     * */
    public void terminByInter() throws InterruptedException {
        ThreadInter threadInter = new ThreadInter();
        log.info("--開啟子線程--");
        threadInter.start();
        Thread.currentThread().sleep(2000);
        flag = true;
        Thread.currentThread().sleep(2000);
        //此時子線程并不會終止,只能通過中斷終止
        threadInter.interrupt();
        log.info("--stop the world--");
    }
    public class ThreadInter extends Thread{
        @Override
        public void run(){
            while(!flag){
                try {
                    Thread.currentThread().join();
                } catch (InterruptedException e) {
                    flag = true;
                }
            }
            log.info("--子線程執(zhí)行完畢--");
        }
    }
}

二 廢棄方式

1 Thread.stop

此方法已經(jīng)廢棄,主要是因為不安全,它是強行終止線程,非常暴力,可能會帶來不可預(yù)知的后果;另調(diào)用stop之后,創(chuàng)建該子線程的線程就會拋出ThreadDeath的error,具體看下源碼:

@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());
    }
2 suspend & resume

這是必須成對使用的方法,要不很容易造成死鎖,在底層都是依賴native方法實現(xiàn)線程的暫停和恢復(fù)。如果該線程沒有被suspend暫停,則無法通過resume恢復(fù)的。
舉例一個死鎖的場景:線程A持有一把鎖,然后A被suspend(不會釋放鎖),線程A等待被resume;線程B的執(zhí)行流程是先獲取這把鎖,再resume線程A,這樣就會造成死鎖。

3 Runtime.runFinalizersOnExit

此方法是線程不安全的,它是依賴Shutdown設(shè)置終結(jié)器(Finalizer),想深入了解的,具體看下源碼:

@Deprecated
    public static void runFinalizersOnExit(boolean var0) {
        SecurityManager var1 = System.getSecurityManager();
        if (var1 != null) {
            try {
                var1.checkExit(0);
            } catch (SecurityException var3) {
                throw new SecurityException("runFinalizersOnExit");
            }
        }

        Shutdown.setRunFinalizersOnExit(var0);
    }

特此聲明:
分享文章有完整的知識架構(gòu)圖,將從以下幾個方面系統(tǒng)展開:
1 基礎(chǔ)(Linux/Spring boot/并發(fā))
2 性能調(diào)優(yōu)(jvm/tomcat/mysql)
3 高并發(fā)分布式
4 微服務(wù)體系
如果您覺得文章不錯,請關(guān)注阿倫故事,您的支持是我堅持的莫大動力,在此受小弟一拜!


每篇福利:

評論區(qū)打出車型.jpg

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

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