Dúvida usando sincronismo em Thread

5 respostas
A

Pessoal, boa tarde.
Estou estudando para tentar a certificação SCJP.
Estava estudando sincronismo, quando me deparei com um exemplo.
O que eu gostaria de entender nesse exemplo, é o porquê de imprimir repetidamente "main".
Ele chama a thread principal que é o main?

public class Duv implements Runnable {
	public void run(){
		synchronized(this){
			for(int z=0;z<2;z++)
				System.out.println(Thread.currentThread().getName());
			notify();
		}
	}
	public static void main(String []args){
		Duv d = new Duv();
		Thread t = new Thread(d);
		
		t.start();
		synchronized(t){
			try{
				t.wait();
				for(int j=0;j<3;j++){
					System.out.println(Thread.currentThread().getName());
				}
			}catch(Exception e){}
		}
	}

}

Aguardo respostas

5 Respostas

E

Bom, na minha máquina o seu exemplo gerou a seguinte saída:

Thread-0
Thread-0
main
main
main

O nome da thread principal do seu programa é “main” e o nome da thread que seu programa iniciou é “Thread-0”.
É a saída esperada desse programa, já que você
a) Iniciou a thread t (cujo nome é “thread-0”)
b) Esperou (com t.wait) que a thread t notificasse a thread principal com t.notify. Note que a thread t deve imprimir 2 vezes o nome dela (Thread-0) antes de chamar notify
c) E na thread principal, depois de esperar a thread t lhe notificar, mandou imprimir 3 vezes o nome da thread principal (cujo nome é main).

Você não está fazendo aquele erro noob de economizar em chaves não, hein? Se você veio do Python, sabe que chaves não existem, mas a tabulação é importante. Em Java, você tem de usar as chaves de qualquer maneira, ou então tomar muito cuidado com o que está fazendo.
Estou imaginando que você estava esperando outra coisa.
Com if e for, mesmo que seja só um comando, sempre ponha chaves. Isso evita erros noobs.

E

Todo programa Java, mesmo que não crie explicitamente threads (como um “hello, world”), tem pelo menos 8 ou 9 threads. A thread principal de seu programa, que é chamada no main, tem nome “main”. Ela não precisa ser criada porque ela já está criada quando se inicia o programa.

Andersonrms

Testei a classe aki algumas vezes e em todas imprimiu:

Thread-0
Thread-0
main
main
main

A classe é inicializada pela thread main, e a partir dessa thread é criada uma outra e a mesma é inicializada. A partir daí o programa possui duas threads, uma com o nome main e a outra com o nome Thread-0.

Não sei explicar direito o funcionamento do synchronized, do wait e do notify. Sei que os dois blocos de execução das duas threads são sincronizados pelo mesmo objeto. Isso significa q quando uma das threads obtém o lock desse objeto, a outra thread não poderá ser executada. O SO decide qual das duas threads executar primeiro.

Se executar o Thread-0 primeiro, esse obterá o lock e executará até o fim, imprimindo Thread-0 duas vezes. Nesse caso eu não sei o q acontece com o notify, pois não teve nenhum wait nesse caso. Acredito q seja desconsiderado. Mas depois disso a Thread-0 morrerá e será executada a main. Ai eu tb não sei o q acontece com o wait, pois não tem nenhuma outra thread, portanto eu acredito q seja desconsiderado tb. E então main será impresso main 3 vezes.

Se executar o main primeiro, esse obterá o lock e executará até o wait. Ai, acredito eu, o processo seja verificar se existe alguma outra thread q tenta obter o msm lock, mas não tenho certeza disso. Se for isso, será encontrada a Thread-0, q será executada até o fim e notificará a umas das threads q estejam esperando. Como só existe uma, a main, essa será executada, produzindo a msm saída da citada anteriormente.

Eu entendi assim, mas não sou nenhum expert. Tô aprendendo tb.

Andre_Fonseca

oi,

A palavra chave synchronized é utilizada em métodos e também em um statement/bloco de código.

Ela impede que mais de uma Thread execute ou método ou o bloco de código ao mesmo tempo.

O wait faz com que a Thread espere até que seja “acordada” por outra Thread.

Para “acordar” uma Thread você pode usar o notify ou o notifyAll (que acorda todas as Threads)

Dá uma lida no tópico abaixo

http://www.guj.com.br/java/53187-wait-e-notify-duvida--resolvido

A

Bem, pelo o que testei melhor aqui e entendi, como a main também é um thread e o código

try{
				t.wait();
				for(int j=0;j<3;j++){
					System.out.println(Thread.currentThread().getName()+j);
				}
			}catch(Exception e){}

fez na verdade um for imprimindo três vezes o nome da thread sendo executada naquele instante, ou seja, a main, visto que a main naquele momento estava com o lock. Foi isso que eu entendi. Por isso imprimiu o lock três vezes. :slight_smile:

Criado 9 de setembro de 2012
Ultima resposta 9 de set. de 2012
Respostas 5
Participantes 4