我只是偶然發現了一個我不能解釋的守護線程奇怪的行爲。我已經減少了我的代碼,以最小的,完整的和可覈查樣本:JVM不會退出,直到守護進程線程未完成
public static void main(String[] args) throws InterruptedException {
Thread runner = new Thread(() -> {
final int SIZE = 350_000;
for (int i = 0; i < SIZE; i++) {
for (int j = i + 1; j < SIZE; j++) {
if (i*j == SIZE * SIZE - 1) {
return;
}
}
}
});
runner.setDaemon(true);
runner.start();
// Thread.sleep(1000);
System.out.println("Exiting.");
}
由runner
線程執行的代碼需要大約12秒至終止我的盒子,我們不感興趣,它做什麼,因爲我只需要花一些時間計算。
如果運行這段代碼,因爲它是,它按預期工作:它只是它的開始後終止。 如果我取消註釋Thread.sleep(1000)
行並運行該程序,它將運行約12秒鐘,然後打印出「退出」並終止。
據我瞭解守護線程如何工作,我預計此代碼運行1秒,然後終止執行,因爲唯一的用戶線程運行是與main()方法啓動的(runner
是一個後臺守護進程線程),只要1000毫秒通過,它就會到達執行結束,並且JVM應該停止。此外,看起來很奇怪,「退出」僅在12秒後打印,而不是在程序啓動時打印。
我錯了嗎?我如何實現所需的行爲(暫停一秒鐘,然後停止,與跑步者線程無關)?
我使用的是Linux中一個64位的Oracle JDK 1.8.0_112,它具有相同的行爲或者如果來自一個IDE或命令行啓動。
謝謝, 安德烈
這_definitely_聽起來很熟悉,但我不太記得了足夠的找到搜索詞,不僅將讓我對了Thread.sleep和守護程序線程背景信息氾濫。 : - \ – yshavit
FWIW,這個工作方式與你在我的盒子上的預期一樣(windows,jdk 1.8.0_31)。你的盒子是多CPU嗎? – user2189998
如果需要,調度程序可以決定在繼續執行主線程之前運行守護線程12秒。沒有任何事物禁止你觀察到的行爲。 –