Qual a razão de querermos que TODAS as classes tenham os métodos wait() e notify() ??? Elas não são usadas apenas por Threads? Então, por que elas não estão na classe Thread, assim como os demais métodos (run(), sleep(), start() e join() ) ???
Justamente porque quem deverá ficar travado é o objeto, não a Thread. Todos os objetos devem saber como travar a si mesmo e a notificar Threads que estejam travadas. Se mais de uma Thread tiver que ser notificada naquele objeto, é menos custoso para o objeto notificar todos que estão parados nele do que para a classe Thread encontrar todos que estão parados em determinado objeto.
[]´s
tem um outro detalhe também, se a classe implementasse Runnable ao invés de herdar thread, isso também quebraria essa lógica…
Primeiro de tudo. A classe Thread não é uma thread. Ela é um disparador, ela inicia uma thread, e coleta informações da thread que iniciou. Mas ela não é a thread.
Entender isso é muito importante. Duas threads diferentes poderão percorrer o mesmo objeto. Tanto que duas threads podem ser disparadas a partir do mesmo Runnable.
Foi uma decisão de projeto do Java que qualquer objeto poderia ser usado como lock, num código sincronizado. Algumas linguagens possuem objetos especiais para isso (de fato, na API de java.util.synchronized, existe o objeto Lock, que seria responsável por isso).
Como essa decisão foi feita, é necessário que o monitor seja capaz de esperar por uma condição, ou notificar a thread de que a condição pode ter sido satisfeita. Por isso, existem esses métodos na classe Object.
Quem fica travada é a thread. O objeto apenas funciona como uma espécie de semáforo. Quando uma thread chega num bloco sincronizado, ela olha o objeto e pergunta “posso passar”? Caso possa, ela entra no código. Caso não possa, ela é enfileirada, e esse objeto controla essa fila.
Quando uma thread dentro do bloco sincronizado encontra um wait(), ela passa a dormir, deixando o trecho sincronizado. Quando uma outra thread chamar notifyAll(), a thread que estava dormindo acorda, e verifica se pode continuar a sua execução. Caso possa, ela volta ao ponto que parou no trecho sincronizado e continua.
Caso contrário, volta a dormir.