第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

當(dāng) Java 中的線程死亡時(shí),ThreadPoolExecutor 會(huì)發(fā)生什么

當(dāng) Java 中的線程死亡時(shí),ThreadPoolExecutor 會(huì)發(fā)生什么

寶慕林4294392 2022-06-30 18:41:10
我創(chuàng)建了一個(gè)線程,該線程又創(chuàng)建一個(gè)ThreadPoolExecutor并向它提交一些長(zhǎng)時(shí)間運(yùn)行的任務(wù)。在某些時(shí)候,原始線程由于未處理的異常/錯(cuò)誤而死亡。執(zhí)行程序應(yīng)該發(fā)生什么(它是那個(gè)死線程的本地,沒有對(duì)其的外部引用)?它應(yīng)該被GCed還是不被GCed?編輯:這個(gè)問題從一開始就被錯(cuò)誤地表述了,但我會(huì)留下它,因?yàn)?Gray 提供了一些關(guān)于 TPE 如何工作的詳細(xì)信息。
查看完整描述

2 回答

?
翻過高山走不出你

TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超3個(gè)贊

executor 會(huì)發(fā)生什么(它是死線程的本地,沒有外部引用)?它應(yīng)該被GCed還是不被GCed?


答案比“是的,如果沒有引用它”更復(fù)雜。這取決于在 中運(yùn)行的線程ThreadPoolExecutor是否仍在運(yùn)行。這又取決于創(chuàng)建的 TPE 類型以及提交給它的“長(zhǎng)時(shí)間運(yùn)行的任務(wù)”是否已完成。


例如,如果任務(wù)尚未完成,則線程仍將運(yùn)行。即使它們已經(jīng)完成,如果您的 TPE 具有未設(shè)置的核心線程,allowCoreThreadTimeOut(true)那么線程也不會(huì)停止。JVM 從不垃圾收集正在運(yùn)行的線程,因?yàn)樗鼈儽徽J(rèn)為是GC“根”:


...根據(jù)定義,正在運(yùn)行的線程對(duì) GC 免疫。GC 通過掃描“根”開始其工作,這些“根”被認(rèn)為始終可以訪問;根包括全局變量(Java-talk 中的“靜態(tài)字段”)和所有正在運(yùn)行的線程的堆棧......


所以下一個(gè)問題是線程是否有引用回,ThreadPoolExecutor我相信他們有。內(nèi)部Worker類是Runnable存儲(chǔ)在其中并由它thread.target執(zhí)行的,Thread因此它不能被GC'd。 Worker并非static如此,它隱含了對(duì)外部ThreadPoolExecutor實(shí)例的引用。該run()方法實(shí)際上是調(diào)用ThreadPoolExecutor.runWorker()引用由ThreadPoolExecutor. 因此,正在運(yùn)行的線程保留對(duì)WorkerTPE 和 TPE 的引用,因此垃圾收集器無法收集 TPE。


例如,這是一個(gè)引用 TPE 的正在運(yùn)行的池線程的典型堆棧幀:


java.lang.Thread.sleep(Native Method)

com.j256.GcTester$1.run(GcTesteri.java:15)

java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)

java.util.concurrent.FutureTask.run(FutureTask.java:266)

>> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

java.lang.Thread.run(Thread.java:748)

但是,如果線程池任務(wù)已全部完成并且它有 0 個(gè)核心線程或核心線程已超時(shí),那么將沒有Worker與ThreadPoolExecutor. 然后 TPE將被垃圾收集,因?yàn)槌?GC 足夠智能可以檢測(cè)到的循環(huán)引用之外,沒有對(duì)它的引用。


這是一個(gè)演示它的小示例測(cè)試程序。finalize()如果有 1 個(gè)核心線程,那么即使工作線程在注意到/tmp/x文件存在后退出,TPE 也永遠(yuǎn)不會(huì)關(guān)閉(通過)。即使主線程沒有引用它也是如此。但是,如果有 0 個(gè)核心線程,那么在線程超時(shí)后(這里是在完成最后一個(gè)任務(wù)后 1 秒后)TPE 將被收集。


public class GcTester {

    public static void main(String[] args) {

        int numCore = 1; // set to 0 to have it GC'd once /tmp/x file exists

        ExecutorService pool =

                new ThreadPoolExecutor(numCore, Integer.MAX_VALUE,

                        1, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()) {

                    protected void terminated() {

                        System.out.println(this + " terminated");

                    }

                };

        pool.submit(new Runnable() {

            public void run() {

                while (true) {

                    Thread.sleep(100); // need to handle exception here

                    if (new File("/tmp/x").exists()) {

                        System.out.println("thread exiting");

                        return;

                    }

                }

            }

        });

        pool = null; // allows it to be gc-able

        while (true) {

            Thread.sleep(1000);  // need to handle exception here

            System.gc();         // pull the big GC handle

        }

    }

}


查看完整回答
反對(duì) 回復(fù) 2022-06-30
?
守著一只汪

TA貢獻(xiàn)1872條經(jīng)驗(yàn) 獲得超4個(gè)贊

線程就是所謂的GC 根。這意味著無法收集正在運(yùn)行(或未啟動(dòng))的線程。這也意味著無法收集從這些線程引用的對(duì)象,這就是為什么您可以執(zhí)行類似的操作new Thread(new MyRunnable()).start(),或者在沒有任何引用的情況下運(yùn)行線程池。

如果線程是一個(gè)守護(hù)進(jìn)程,如果所有其他非守護(hù)線程都停止了,它可以自動(dòng)停止。您可以擁有帶有守護(hù)線程的線程池,但最好的辦法是確保正確清理事物(即異常不應(yīng)終止本應(yīng)最終停止并清理線程池的線程)。


查看完整回答
反對(duì) 回復(fù) 2022-06-30
  • 2 回答
  • 0 關(guān)注
  • 286 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)