Thread

9 respostas
rodrigo_lm

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.

Obrigado…

9 Respostas

rodrigo_lm

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:

synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }

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

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.

rodrigo_lm

Obrigado Sergio, você entendeu perfeitamente minha duvida.

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:

public class Teste extends Thread{
 	public void restart(){
 		startMe();
 	}
 	public void startMe(){
 		synchronized(this){
 			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[]) throws Exception{
 		H t1 = new H();
 		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.

Agora entendi, obrigado :smiley:

Criado 13 de outubro de 2006
Ultima resposta 17 de out. de 2006
Respostas 9
Participantes 5