1. 概要

この短い記事では、Javaのデーモンスレッドを見て、それらが何に使用できるかを確認します。 また、デーモンスレッドとユーザースレッドの違いについても説明します。

2. デーモンスレッドとユーザースレッドの違い

Javaには、ユーザースレッドとデーモンスレッドの2種類のスレッドがあります。

ユーザースレッドは優先度の高いスレッドです。 JVMは、ユーザースレッドがタスクを完了するのを待ってから終了します。

一方、デーモンスレッドは優先度の低いスレッドであり、その唯一の役割はユーザースレッドにサービスを提供することです。

デーモンスレッドはユーザースレッドにサービスを提供することを目的としており、ユーザースレッドの実行中にのみ必要になるため、すべてのユーザースレッドの実行が終了した後、JVMの終了を妨げることはありません。

そのため、デーモンスレッドに通常存在する無限ループは問題を引き起こしません。これは、 finally ブロックを含むコードは、すべてのユーザースレッドが実行を終了すると実行されないためです。 このため、デーモンスレッドはI/Oタスクには推奨されません。

ただし、この規則には例外があります。 デーモンスレッドのコードが適切に設計されていないと、JVMが終了できなくなる可能性があります。 たとえば、実行中のデーモンスレッドで Thread.join()を呼び出すと、アプリケーションのシャットダウンをブロックできます。

3. デーモンスレッドの使用

デーモンスレッドは、ガベージコレクション、未使用オブジェクトのメモリの解放、キャッシュからの不要なエントリの削除などのバックグラウンドサポートタスクに役立ちます。 ほとんどのJVMスレッドはデーモンスレッドです。

4. デーモンスレッドの作成

スレッドをデーモンスレッドに設定するには、呼び出すだけです。 Thread.setDaemon()。 この例では、 新しいスレッドを拡張するクラススレッドクラス:

NewThread daemonThread = new NewThread();
daemonThread.setDaemon(true);
daemonThread.start();

すべてのスレッドは、それを作成したスレッドのデーモンステータスを継承します。メインスレッドはユーザースレッドであるため、mainメソッド内で作成されるスレッドは、デフォルトでユーザースレッドです。

メソッドsetDaemon()は、 Thread オブジェクトが作成され、スレッドが開始されていない場合にのみ呼び出すことができます。 スレッドの実行中にsetDaemon()を呼び出そうとすると、IllegalThreadStateExceptionがスローされます。

@Test(expected = IllegalThreadStateException.class)
public void whenSetDaemonWhileRunning_thenIllegalThreadStateException() {
    NewThread daemonThread = new NewThread();
    daemonThread.start();
    daemonThread.setDaemon(true);
}

5. スレッドがデーモンスレッドであるかどうかの確認

最後に、スレッドがデーモンスレッドであるかどうかを確認するには、メソッド isDaemon()を呼び出すだけです。

@Test
public void whenCallIsDaemon_thenCorrect() {
    NewThread daemonThread = new NewThread();
    NewThread userThread = new NewThread();
    daemonThread.setDaemon(true);
    daemonThread.start();
    userThread.start();
    
    assertTrue(daemonThread.isDaemon());
    assertFalse(userThread.isDaemon());
}

6. 結論

このクイックチュートリアルでは、デーモンスレッドとは何か、およびいくつかの実際的なシナリオでそれらを使用できることを確認しました。

いつものように、コードのフルバージョンはGitHubから入手できます。