私は説明できないデーモンスレッドの不思議な振る舞いに直面しました。私は、最小限の完全かつ検証可能なサンプルに私のコードを削減しました:デーモンスレッドが完了しないうちに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を停止する必要があります。また、 "Exiting"は12秒後にのみ印刷され、プログラムの起動時には印刷されません。
は私が間違っていますか?どのようにして目的の動作を達成できますか(1秒間停止してから、ランナースレッドの動作とは独立して停止します)。
私は64ビットのOracle JDK 1.8.0_112をLinuxボックスで使用しています。これは、IDEまたはコマンドラインから起動した場合と同じ動作をします。それは、そのメインメソッドから戻る前
おかげで、 アンドレア
これはよく知られていますが、私はThread.sleepとdeamonスレッドの背景情報があふれないだけの検索語を見つけるのに十分な記憶はありません。 : - \ – yshavit
FWIW、これはあなたが私のボックス(Windows、jdk 1.8.0_31)で期待するように動作します。あなたのボックスはマルチCPUボックスですか? – user2189998
スケジューラは、メインスレッドの実行を再開する前に12秒間デーモンスレッドを実行することができます。あなたが観察した行動を禁じるものは何もありません。 –