ここの誰もがRunnableを実装するのが最善の方法だと思っているようですが、私はそれらに同意しませんが、私の意見ではThreadを拡張することもあります。
Runnableを実装する場合、Runnableを実装するクラスはスレッド名を制御できません。次のように、スレッド名を設定できるのは呼び出しコードです。
new Thread(myRunnable,"WhateverNameiFeelLike");
ただし、Threadを拡張すると、クラス内でこれを管理できます(例のように、スレッドに「ThreadB」という名前を付けます)。この場合、あなたは:
A)デバッグのために、より便利な名前を付けることができます
B)その名前をそのクラスのすべてのインスタンスに使用することを強制しています(スレッドであるという事実を無視し、Runnableであるかのようにそれを使用して上記を実行する場合を除きますが、ここでは慣例について話し合っているため、私が感じるその可能性を無視してください)。
たとえば、その作成のスタックトレースを取得し、それをスレッド名として使用することもできます。これは奇妙に思えるかもしれませんが、コードの構造によっては、デバッグに非常に役立ちます。
これは小さなことのように思えるかもしれませんが、多くのスレッドを含む非常に複雑なアプリケーションがあり、突然すべてが「停止」しました(デッドロックの理由またはネットワークプロトコルの欠陥のため)明らか-またはその他の無限の理由)次に、すべてのスレッドが「Thread-1」、「Thread-2」、「Thread-3」と呼ばれるJavaからスタックダンプを取得することは、必ずしも非常に有用であるとは限りません(スレッドの状態によって異なります)構造化されており、スタックトレースによってどれがどれであるかを有益に判断できるかどうか-すべてが同じコードを実行している複数のスレッドのグループを使用している場合は、常に可能とは限りません)。
もちろん、名前をその作成呼び出しのスタックトレースに設定するスレッドクラスの拡張を作成し、それを標準のJavaスレッドクラスの代わりにRunnable実装で使用することにより、上記を一般的な方法で実行することもできます。 (下記を参照)しかし、スタックトレースに加えて、デバッグ用のスレッド名に役立つコンテキスト固有の情報(スレッドが処理できる多くのキューまたはソケットの1つへの参照など)がある場合があります。その場合のためにThreadを拡張して、コンパイラーに(またはライブラリーを使用している他の)特定の情報(たとえば、問題のキュー/ソケット)を渡して名前で使用させることができます。
以下は、呼び出しスタックトレースを名前として持つ一般的なスレッドの例です。
public class DebuggableThread extends Thread {
private static String getStackTrace(String name) {
Throwable t= new Throwable("DebuggableThread-"+name);
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
t.printStackTrace(ps);
return os.toString();
}
public DebuggableThread(String name) {
super(getStackTrace(name));
}
public static void main(String[] args) throws Exception {
System.out.println(new Thread());
System.out.println(new DebuggableThread("MainTest"));
}
}
2つの名前を比較した出力のサンプルを次に示します。
Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
at DebuggableThread.getStackTrace(DebuggableThread.java:6)
at DebuggableThread.<init>(DebuggableThread.java:14)
at DebuggableThread.main(DebuggableThread.java:19)
,5,main]