Thread - Ordem de execução

Olá!

Eu tenho um programa que usa thread. Eu andei debugando esse código e gostaria que alguém me fizesse o favor de dizer se estou certo na minha interpretação.


public class TesteThread 
{
	private static boolean stop;
	
	private static synchronized void setStop()
	{
		stop = true;
	}
	
	private static synchronized boolean getStop()
	{
		//System.out.println(stop);
		return stop;
	}
	
	public void run()
	{
		System.out.print("W");
	}
	
	public static void main(String []args) throws InterruptedException
	{
		
		Thread t = new Thread(new Runnable(){
			public void run()
			{
				int n = 0;
				System.out.print("X");
				
				
				while(!getStop())
				{
					n++;
				}
				
				System.out.print("Y");
			}
		});
		
		//System.out.println(getStop());
		t.start();
		Thread.sleep(10000);
		setStop();
		System.out.print("Z");
	}
}

Quando o programa começa a ser executado, ele vai passa pela definição da Thread e depois vai até t.start().
A partir daí, começa uma execução paralela. Enquanto a thread imprime “X” e fica presa no looping, paralelamente, a thread é colocada para dormir por 10 segundos, em Thread.sleep(10000).
O programa continua sendo executado, indo agora para setStop(). Enquanto isso, a thread ainda está adormecida.
A seguir, “Z” é impressa. Enquanto isso, o prazo de 10 segundos se passa, a thread verifica o loop e vê que a condição mudou. Ela sai do loop e imprime “Y”.

Quando testei no Eclipse, primeiro imprime x, depois espera 10 segundos, imprime Z e depois Y. Achei que deveria imprimir X, depois Z, esperar 10 segundos (um pouco menos) e imprimir Y.

Bem, o engraçado é que a resposta desse programa é “XYZ”.

Alguém me auxilia?

O teu problema está na interpretação de Thread.sleep. Este comando faz dormir a própria thread onde é executado e não outra.

Assim, a thread principal é que dorme 10 segundos enquanto a outra fica executando o ciclo de verificação. Quando a thread principal acorda, altera a condição e então imprime Z ao mesmo tempo que a outra thread sai do ciclo e imprime Y.

A saída não é garantidamente XYZ, podendo haver situações em que seja XZY.

[quote=pmlm]O teu problema está na interpretação de Thread.sleep. Este comando faz dormir a própria thread onde é executado e não outra.

Assim, a thread principal é que dorme 10 segundos enquanto a outra fica executando o ciclo de verificação. Quando a thread principal acorda, altera a condição e então imprime Z ao mesmo tempo que a outra thread sai do ciclo e imprime Y.

A saída não é garantidamente XYZ, podendo haver situações em que seja XZY.[/quote]

Muito obrigado por ter exclarecido…

Mas por que não é garantida a ordem de saída? Todas as vezes que rodei, o resultado foi o mesmo!

Olhando o código novamente, eu entendi o que vc quis dizer…

Por exemplo, pode ser que quando estiver acabado de terminar de verificar se entra no loop ou não (imediatamente após), os 10 segundos terminam…assim, setStop() é realizado enquanto que n é incrementado. Aí, é impresso Z e depois Y.

Mas pode ocorrer tb que os 10 segundos terminam, setStop() é executado. Nesse tempo, acaba o loop e Y é impresso. Após, Z.

O seu toque foi fundamental para eu enxergar isso!