Boa tarde pessoal, estava estudando e não consegui entender o seguinte exercicio:
public class H extends Thread{
public void restart(){
startMe();
}
public void startMe(){
synchronized(H.class){
H.class.notifyAll();
System.out.println("Trying to Notify");
}
}
public void run(){
try{
synchronized(this){
wait();
System.out.println("Notified");
}
}catch(InterruptedException e){}
}
public static void main(String a[]){
H t1 = new H();
t1.start();
t1.restart();
}
}
A saida deste programa é: Trying to Notify, até ai tudo bem, mas fui tentar alterar o codigo para que a saida seja Trying to Notify Notified, mas não estou conseguindo…
Alguem poderia me ajudar, e se puder me explicar como funciona as chaves do metodo synchronized, pois já lí diversos textos a respeito mas não consegui entender ainda.
Alguem ao menos poderia me indicar um material para estudar este assunto [tirando o livro da kathy…]
[]´s
diego2005
Indique um tempo de espera, ou seja, passe um parâmetro para wait():
T+
diego2005
Quando você chama wait() sem parâmetro ele fica esperando a liberação do objeto (uma chamada a notify()). Quando você indica um tempo, ele espera a liberação do objeto pelo tempo determinado
public final void wait()
throws InterruptedExceptionCauses current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object’s monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object’s monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
This method should only be called by a thread that is the owner of this object’s monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.
rodrigo_lm
Diego… obrigado pela resposta, mas essa parte eu já tinha entendido…
Minha duvida é sobre as chaves…
synchronized(H.class){}
synchronized(this){}
Estou tentando modificar o codigo para que o metodo notifyAll(), coloque a thread de volta em modo execução, para poder entender as chaves dos blocos de codigo que usam synchronized()
L
leandrold
Cara.
Isso é uma Thread, creio que vc ja sabe disso.
A palavra synchronized garante exclusão mutua, ou seja so um acessa por vez aquela parte do codigo.
Se t1 fosse passada o outro objeto que chama-se o run() poderia ocorrer de duas threads acessarem a memsa região , logo com synchronized isso não ocorre.
A sua thread e inicia com star , o start da thread procura o metodo run, o seu run, garante exclusão muta (synchronized ) e logo em seguida dorme, ate que alguem há acorde. Note que vc chama t1.restart(), isto que faz sua thread acordar, entretando a saida vc disse que é Trying to Notify Notified, entretando esse programa não garante que isso sempre ocorrera. pode sair
Notified Trying to Notify por exemplo ou não sair nda se a operação t1.restart() for mais rapida que a criação e execução da thread.
sergiolopes
Não sei se entendi sua dúvida, mas acho que o problema aqui é onde está sendo feito o synchronized e onde se está chamando wait/notify.
Perceba que no run() o synchronized e a chamada ao wait são feitas no objeto this. E no restart() o synchronized e a chamada ao notifyAll() são feitas no H.class.
this e H.class são objetos diferentes!!! Por isso que o wait vai ficar esperando eternamente e nunca vai ser impressa a mensagem que você queria. E o notifyAll vai acabar é não notificando ninguém já que não há ninguém com wait no H.class.
Lembre que o this é a referência especial à instância da classes. E o H.class é algo como um atributo estático que devolve um objeto Class que representa aquela classe.
Eu tentei de todas as formas modificar as chaves para que o metodo notifyAll() desapertasse a thread, mas não consegui… Essa é minha duvida, como modificar o codigo, para que as chaves fiquem iguais e o metodo notifiAll() funcione.
Muito obrigado…
marcelo_mococa
tente assim:
publicclassTesteextendsThread{publicvoidrestart(){startMe();}publicvoidstartMe(){synchronized(this){notifyAll();System.out.println("Trying to Notify");}}publicvoidrun(){try{synchronized(this){wait();System.out.println("Notified");}}catch(InterruptedExceptione){}}publicstaticvoidmain(Stringa[])throwsException{Ht1=newH();t1.start();Thread.sleep(2000);t1.restart();}}
vc deve trabalhar com o bloqueio do mesmo objeto.
O sleep é necessário porque você não tem certeza de quando o escalonador de threads vai escalonar a thread que você iniciou. Com este sleep, garantimos que a thread já terá executado quando chamarmos o método restart.
t+
rodrigo_lm
marcelo_mococa, muito obrigado…
Tinha tentado desta forma, mas não tinha usado o sleep(), por isso que não estava dando certo.