Tout le monde ici semble penser que l'implémentation de Runnable est la voie à suivre et je ne suis pas vraiment en désaccord avec eux, mais il y a aussi un argument pour étendre Thread à mon avis, en fait, vous l'avez en quelque sorte démontré dans votre code.
Si vous implémentez Runnable, la classe qui implémente Runnable n'a aucun contrôle sur le nom du thread, c'est le code appelant qui peut définir le nom du thread, comme ceci:
new Thread(myRunnable,"WhateverNameiFeelLike");
mais si vous étendez Thread, vous pouvez gérer cela au sein de la classe elle-même (tout comme dans votre exemple, vous nommez le thread 'ThreadB'). Dans ce cas, vous:
A) pourrait lui donner un nom plus utile à des fins de débogage
B) forcent à ce que ce nom soit utilisé pour toutes les instances de cette classe (à moins que vous ignoriez le fait qu'il s'agit d'un thread et que vous fassiez ce qui précède comme s'il s'agissait d'un Runnable, mais nous parlons ici de convention dans tous les cas, donc ignorer cette possibilité que je ressens).
Vous pouvez même par exemple prendre une trace de pile de sa création et l'utiliser comme nom de thread. Cela peut sembler étrange, mais selon la structure de votre code, il peut être très utile à des fins de débogage.
Cela peut sembler être une petite chose mais où vous avez une application très complexe avec beaucoup de threads et tout d'un coup, les choses se sont «arrêtées» (soit pour des raisons de blocage ou peut-être à cause d'une faille dans un protocole réseau qui serait moins évidente - ou d'autres raisons infinies), puis obtenir un vidage de pile à partir de Java où tous les threads sont appelés «Thread-1», «Thread-2», «Thread-3» n'est pas toujours très utile (cela dépend de la façon dont vos threads sont structuré et si vous pouvez dire lequel est juste par leur trace de pile - pas toujours possible si vous utilisez des groupes de plusieurs threads exécutant tous le même code).
Cela dit, vous pouvez bien sûr également faire ce qui précède de manière générique en créant une extension de la classe de threads qui définit son nom sur une trace de pile de son appel de création, puis l'utiliser avec vos implémentations Runnable au lieu de la classe de thread Java standard (voir ci-dessous) mais en plus de la trace de la pile, il pourrait y avoir plus d'informations spécifiques au contexte qui seraient utiles dans le nom du thread pour le débogage (une référence à l'une des nombreuses files d'attente ou sockets qu'il pourrait traiter, par exemple, auquel cas vous pourriez préférer étendez Thread spécifiquement pour ce cas afin que le compilateur vous force (ou que d'autres utilisent vos bibliothèques) à passer certaines informations (par exemple la file d'attente / socket en question) pour une utilisation dans le nom).
Voici un exemple de thread générique avec la trace de pile appelante comme nom:
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"));
}
}
et voici un échantillon de la sortie comparant les deux noms:
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]