Todos aqui parecem pensar que implementar o Runnable é o caminho a percorrer e eu realmente não discordo deles, mas também há um motivo para estender o Thread na minha opinião, na verdade, você meio que demonstrou isso no seu código.
Se você implementar Runnable, a classe que implementa Runnable não tem controle sobre o nome do encadeamento, é o código de chamada que pode definir o nome do encadeamento, assim:
new Thread(myRunnable,"WhateverNameiFeelLike");
mas se você estender o Thread, poderá gerenciar isso dentro da própria classe (assim como no seu exemplo, você nomeará o segmento 'ThreadB'). Nesse caso, você:
A) pode dar a ele um nome mais útil para fins de depuração
B) estão forçando que esse nome seja usado para todas as instâncias dessa classe (a menos que você ignore o fato de que é um encadeamento e faça o acima com ele como se fosse um Runnable, mas estamos falando de convenção aqui em qualquer caso, portanto, pode ignore essa possibilidade que sinto).
Você pode, por exemplo, pegar um rastreio de pilha de sua criação e usá-lo como o nome do encadeamento. Isso pode parecer estranho, mas dependendo da estrutura do seu código, pode ser muito útil para fins de depuração.
Isso pode parecer uma coisa pequena, mas onde você tem um aplicativo muito complexo com muitos threads e de repente coisas "pararam" (por razões de conflito ou possivelmente por causa de uma falha em um protocolo de rede, seria menos óbvio - ou por outras razões sem fim), obter um despejo de pilha do Java, onde todos os threads são chamados 'Thread-1', 'Thread-2', 'Thread-3' nem sempre é muito útil (depende de como seus threads são estruturado e se é útil saber qual é qual apenas pelo rastreamento da pilha - nem sempre é possível se você estiver usando grupos de vários threads executando o mesmo código).
Dito isto, é claro que você também pode fazer o acima de uma maneira genérica, criando uma extensão da classe thread que define seu nome para um rastreamento de pilha de sua chamada de criação e, em seguida, use isso com suas implementações Runnable em vez da classe Thread Java padrão (veja abaixo), mas, além do rastreamento da pilha, pode haver mais informações específicas do contexto que seriam úteis no nome do encadeamento para depuração (uma referência a uma das muitas filas ou soquetes que ele poderia processar, por exemplo, caso em que você prefere estenda o Thread especificamente para esse caso, para que o compilador force você (ou outras pessoas usando suas bibliotecas) a transmitir determinadas informações (por exemplo, a fila / soquete em questão) para uso no nome).
Aqui está um exemplo do encadeamento genérico com o rastreamento da pilha de chamada como seu nome:
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"));
}
}
e aqui está uma amostra da saída comparando os dois nomes:
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]