Note que o run sendo chamado é do objeto “t”, que não possue uma implementação de “run”. Mas quando “t” chama o método “start”, o método “run” do objeto Threads3 é chamado, e aí escreve “running” na tela.
Como assim Douglas? O Objeto ‘t’ possui sim a implementação de run()!!! O que eu estou questionando é que, às vezes, o código imprime 3 vezes “running” e, outras vezes, imprime apenas uma vez. Para mim, deveria imprimir SEMPRE 3 vezes!!! Essa é minha pergunta!
Hum… foi falha minha. Eu pensei errado pelo seguinte. No código que você passou, quem está implementando o método “run” é a classe Threads3. Este método é chamado quando você chama “start” em “t”. Quando você chama “t.run()”, t está chamando o método “run” de Threads3.
Bom, quanto a sua dúvida, eu fiz um teste aqui e ta escrevendo Running sempre 3 vezes. Desculpe ae se não fui de muita ajuda.
De boa Douglas! Então está saindo sempre 3 vezes no seu? :shock: Estranho… Acabei de refazer o teste aqui. No meu, as vezes sai apenas uma vez também. Vamos esperar para ver se alguém sabe o que está acontecendo.
bem vamos lá com o run eh um metodo como qualquer outro, que vc está chamando e o start() vc faz diz a jvm que usa thread está pronta a executar, cabe a jvm executar ou nao. lembre-se com threads nao há garantias. veja se esse meu post ajuda.
Cara, quando você usa o método start, ele não é garantido que a nova thread que você iniciou vai ser executada na hora.
Existem claramente mais de uma possibilidade neste código.
Primeiro: O start que você usou na thread não executa uma nova thread no exato momento, executando primeiro as 2 linhas de código seguintes que são os 2 run’s, printando 2 vezes na tela a sua mensagem. E em seguida, aquele método start que você chamou antes executa depois, resultando em 3 mensagens.
Segundo: O start pode executar a thread antes dos métodos run que você chamou(algo só aparentemente mais “normal”), printando na tela apenas 1 vez a sua mensagem. As outras 2 chamadas do método run são inúteis, pois uma vez que o método start é executado e completado a sua execução a thread muda para o estado TERMINATED, onde essas chamadas de run não são válidas, não se pode usar uma thread no estado TERMINATED.
Faça testes com o método da classe Thread getState() e veja os 6 estados possíveis da Thread: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING e TERMINATED.
Pelas regras, deve sempre ser escrito running três vezes. Não existe isso de que se uma thread morrer os comandos após a chamada dessa thread não serem executados. Tudo sempre é executado, a não ser que haja um comando como esse na main
Thread.currentThread().setDaemon(true);
ou um wait ou algo do tipo.
Eu acho (e agora estou especulando) que foi algum problema do SO em si, alguma inconsistência.
Ele está certo. O método start da classe thread faz o seguinte:
a) Se a thread está associada a um Runnable, dispara a thread no método run() desse runnable;
b) Caso contrário, dispara o método run() de si mesmo.
No caso do seu código, a Thread t foi criada diretamente da classe Thread e, portanto, não tem o método run() implementado. Quando você dispara pelo start, cai na condição a), e o método run() de Threads3, que está associada, é disparado.
Quando você chama o run(), você está chamando o run() de Thread, que não está implementado.
Ele está certo. O método start da classe thread faz o seguinte:
a) Se a thread está associada a um Runnable, dispara a thread no método run() desse runnable;
b) Caso contrário, dispara o método run() de si mesmo.
No caso do seu código, a Thread t foi criada diretamente da classe Thread e, portanto, não tem o método run() implementado. Quando você dispara pelo start, cai na condição a), e o método run() de Threads3, que está associada, é disparado.
Quando você chama o run(), você está chamando o run() de Thread, que não está implementado.[/quote]]]
ViniGodoy, por esse seu raciocínio, não era para imprimir sempre apenas uma vez “running” então? Você afirmou que “Quando você chama o run(), você está chamando o run() de Thread, que não está implementado” o que eu discordo. Eu sobreescrevi ele na minha classe Threads3. Porque ao fazer t.run(); não iria ser chamado esse run() que eu sobreescrevi? Cade o polimorfismo ai?
Pelas regras, deve sempre ser escrito running três vezes. Não existe isso de que se uma thread morrer os comandos após a chamada dessa thread não serem executados. Tudo sempre é executado, a não ser que haja um comando como esse na main
Thread.currentThread().setDaemon(true);
ou um wait ou algo do tipo.
Eu acho (e agora estou especulando) que foi algum problema do SO em si, alguma inconsistência.[/quote]
renamed, eu também acho que não tem essa de que, se a thread morrer, não se pode mais chamar o run(); O run é um método public qualquer. Ele pode ser chamado SEMPRE. O que não se pode chamar é o start() mais de uma vez, caso contrário, uma exceção é lançada. Mesmo após a thread terminar o método run(), não se pode executar o start novamente.
Agora, a minha dúvida persiste Vc fez testes ae também renamed? O que está imprimindo?
[quote=TiagoTC]ViniGodoy, por esse seu raciocínio, não era para imprimir sempre apenas uma vez “running” então? Você afirmou que “Quando você chama o run(), você está chamando o run() de Thread, que não está implementado” o que eu discordo. Eu sobreescrevi ele na minha classe Threads3.
Porque ao fazer t.run(); não iria ser chamado esse run() que eu sobreescrevi? Cade o polimorfismo ai?[/quote]
Só um detalhe. O fato de executar o run não tem nada a ver com polimorfismo.
t é do tipo Thread, não do tipo Threads3. Ele não teria obrigação nenhuma de executar o seu run(), exceto pela forma como é implementado. Não é uma questão de polimorfismo. O polimorfismo só ocorreria se Threads3 fosse filho de thread, implementasse o método run(), e você criasse t como o tipo Threads3. Então, chamar o start() faria disparar o run() de Threads3, pois ele estaria sobrescrito na classe.
Estou no Linux. Faço “javac Threads3.java” para compilar e “java Threads3” para executar. Tudo na linha de comando mesmo. Aqui ou imprime 3 vezes “running” ou apenas uma vez…
[quote=ViniGodoy][quote=TiagoTC]ViniGodoy, por esse seu raciocínio, não era para imprimir sempre apenas uma vez “running” então? Você afirmou que “Quando você chama o run(), você está chamando o run() de Thread, que não está implementado” o que eu discordo. Eu sobreescrevi ele na minha classe Threads3.
Porque ao fazer t.run(); não iria ser chamado esse run() que eu sobreescrevi? Cade o polimorfismo ai?[/quote]
Só um detalhe. O fato de executar o run não tem nada a ver com polimorfismo.
t é do tipo Thread, não do tipo Threads3. Ele não teria obrigação nenhuma de executar o seu run(), exceto pela forma como é implementado. Não é uma questão de polimorfismo. O polimorfismo só ocorreria se Threads3 fosse filho de thread, implementasse o método run(), e você criasse t como o tipo Threads3. Então, chamar o start() faria disparar o run() de Threads3, pois ele estaria sobrescrito na classe.[/quote]
Humm, é verdade, eu havia esquecido que estava implementando Runnable e não estendendo de Thread. Vlw pela explicação! :thumbup:
Mas, voltando à pergunta inicial. Será que o fato de não estar exibindo sempre 3 vezes “running” aqui seja por algum problema na JVM ?
Me veio outra dúvida agora. Imagina que, ao dar o t.start(), a thread não comece a executar o run() imediatamente naquele momento. Então, os outros 2 códigos serão executados ( t.run() e t.run() ), imprimindo 2 vezes “running” na tela. E se a thread main chegar ao final do seu bloco sem a thread t ter começado sua execução? Então, neste caso, iria acabar imprimindo apenas 2 vezes “running”, não? Pode acontecer esse caso?
Estranho, imprimir uma vez nem sequer faz sentido, já que você tem duas chamadas a t.run(). Mesmo que não houvesse aquele start(), pelo menos 2 vezes teria que ser impresso.