Uso de Wait/Notify - Thread

4 respostas
L

Oi gente, tudo bem?
Será que voce poderiam me explicar porque a saída do programa abaixo é mais ou menos assim?
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste2
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1
teste1

Pelo que eu entendi desse códico, as saídas não deveriam ser alternadas?
teste1
teste2
teste1
teste2
teste1
teste2
teste1
teste2
teste1
teste2
teste1
teste2
teste1
teste2
teste1
teste2

class T1 extends Thread {
	private T2 t2;

	public T1(T2 t2) { this.t2 = t2; }

	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("teste1");
			try {
				t2.notify();
				//wait();
			} catch (Exception e) {}
		}
	}
}

class T2 extends Thread {
	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("teste2");
			try {
				wait();
				//notify();
			} catch (Exception e) {}
		}
	}
}

public class Exemplo {
	public static void main(String args[]) {
		T2 t2 = new T2();
		T1 t1 = new T1(t2);

		t2.start();
		t1.start();
	}
}

4 Respostas

marco-oliveira

não sei se estou falando besteira, mais threads são aleatórias…

S

Meu conhecimento em Threads é muito limitado (por enquanto) mas até aonde eu sei é a JVM quem decide qual thread será executada em tempo de execução. Não tem como você “prever”.

L

Mas como a cada iteraçao do for da trhead2 ela executa uma chamada a wait(), eu pensei que ela ficaria inativa até que uma iteração do for da trhead1 fosse executado e notificasse a tread2…

for (int i = 0; i < 1000; i++) {  
            System.out.println("teste2");  
            try {  
                wait();  
            } catch (Exception e) {}  
        }
for (int i = 0; i < 1000; i++) {  
            System.out.println("teste1");  
            try {  
                t2.notify();  
                //wait();  
            } catch (Exception e) {}  
        }

Mas então a thread ser notificada não implica em ela ser necessariamente executada no instante em que foi notificada?
Ela simplesmente entra na fila de processos prontos a serem executados?

rmendes08
public class ThreadTest {
	public static void main(String[] args) {
		PrinterMonitor monitor = new PrinterMonitor();
		
		ConcurrentPrinter p1 = new ConcurrentPrinter("teste 1", monitor);
		ConcurrentPrinter p2 = new ConcurrentPrinter("teste 2", monitor);
		
		p1.start();
		p2.start();
		
		try {
			p1.join();
			p2.join();
		} catch (InterruptedException e) {
			System.out.println("Threads interrompidas");
		}
	}
}

class ConcurrentPrinter extends Thread{
	private static final int MAX_ITERATIONS = 10;
	
	private final String message;
	private final PrinterMonitor monitor;
	
	public ConcurrentPrinter(String message, PrinterMonitor monitor) {
		this.message = message;
		this.monitor = monitor;
	}

	public void doPrint() throws InterruptedException{
		synchronized (monitor) {
			for(int i = 0 ; i < MAX_ITERATIONS ; i++){
				
				while(monitor.getLastPrinter() == this){
					monitor.wait();
				}
				
				System.out.println(message);
				
				monitor.setLastPrinter(this);
				monitor.notifyAll();
			}
		}
	}
	
	@Override
	public void run() {
		try {
			doPrint();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class PrinterMonitor{
	private ConcurrentPrinter lastPrinter;

	public ConcurrentPrinter getLastPrinter() {
		return lastPrinter;
	}

	public void setLastPrinter(ConcurrentPrinter lastPrinter) {
		this.lastPrinter = lastPrinter;
	}
}

Para que wait() e notify() funcionem você precisa usá-los dentro de um bloco synchronized{}. Além disso, o controle deve ser feito através de um objeto chamado de monitor, que é quem controla a entrada da thread na região crítica.

Criado 27 de junho de 2012
Ultima resposta 27 de jun. de 2012
Respostas 4
Participantes 4