Dúvida Wait() e notify()

Bom estou tentando fazer a classe controlador pausar e reiniciar a classe thread_. Alguém sabe me dizer porquê nâo está funcionando.

Tentei usar os métodos na propria classe thread_ e na classe controlador mas nenhum funcionou.


package cd;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Controle extends Thread {

    Thread_ t1 = new Thread_("thread 1");
    Thread_ t2 = new Thread_("thread 2");
    Thread_ t3 = new Thread_("thread 3");
    Banco banco = new Banco();
    ArrayList<Lista> resultSet = new ArrayList<Lista>();
    private boolean statusAnterior = false;

    public void run() {
        this.carregarArraylist();
        this.iniciarThreads();
        while (true) {
            this.pausarThreads();
            this.reIniciarThreads();
        }
    }

    private void carregarArraylist() {
        banco.carregarArrayList(resultSet);
        statusAnterior = !resultSet.isEmpty();
    }

    private void pausarThreads() {
        try {
            t1.aguardar();
            t2.aguardar();
            t3.aguardar();
        } catch (Exception ex) {
            System.err.print(ex + " pausar Threads");
        }
    }

    private void reIniciarThreads() {
        System.out.println("Iniciou");
            t1.notify();
        synchronized (t1) {
            System.out.println("Iniciou");
            t1.notify();
        }
        synchronized (t2) {
            System.out.println("Iniciou");
            t1.notify();
        }
        synchronized (t3) {
            System.out.println("Iniciou");
            t1.notify();
        }
    }

    private void iniciarThreads() {
        try {
            t1.start();
            t2.start();
            t3.start();
            System.err.println("Threads iniciadas");
        } catch (Exception ex) {
            System.err.print(ex + " Reiniciar Threads");
        }
    }

    private void enviarRequisicao() {
    }

    private void dormir(int time) {
        try {
            sleep(time);
        } catch (Exception ex) {
            System.err.print(ex);
        }
    }

    private void verificarStatusLista() {
        if (!resultSet.isEmpty() != statusAnterior) {
            if (!resultSet.isEmpty()) {
                this.reIniciarThreads();
            } else {
                this.pausarThreads();
            }
        }
    }

    public void aguardar() {
        synchronized (t1) {
            try {
                System.out.println("t1  wait");
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Thread_.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        synchronized (t2) {
            try {
                System.out.println("t2  wait");
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Thread_.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        synchronized (t3) {
            try {
                System.out.println("t3  wait");
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Thread_.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
package cd;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Thread_ extends Thread {

    private String message = "";
     boolean x = true;
    public Thread_(String message) {
        this.message = message;
    }

    public void run() {
        while (true) {
            System.out.println(message);
        }
    }

    public void receberSolicitacao(Lista lista) {
    }

    public void aguardar() {
        synchronized (this) {
            try {
                System.out.println(message + "  wait");
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(Thread_.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void dormir(int time) {
        try {
            sleep(time);
        } catch (Exception ex) {
            System.err.print(ex);
        }
    }
}

Quem tem que chamar o wait() é a própria thread que vai parar, não uma thread externa. No seu código, quem está chamando o wait é o aguardar, que está sendo chamado pela thread Controle.

Cuidado objetos != threads. Você está chamando o método aguardar() pela thread controle, usando como lock o objeto t1, t2, t3 que descrevem as threads t1, t2 e t3, em execução.


package cd;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Thread_ extends Thread {

    private String message = "";
     boolean x = true;
    public Thread_(String message) {
        this.message = message;
    }

    public void run() {
        while (true) {
            System.out.println(message);
        }
    }

    public void receberSolicitacao(Lista lista) {
    }

    public synchronized void aguardar() {
            try {
                System.out.println(message + "  wait");
                wait();
            } catch (InterruptedException ex) {
               Logger.getLogger(Thread_.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
package cd;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Controle extends Thread {

    Thread_ t1 = new Thread_("thread 1");
    Thread_ t2 = new Thread_("thread 2");
    Thread_ t3 = new Thread_("thread 3");
    Banco banco = new Banco();
    ArrayList<Lista> resultSet = new ArrayList<Lista>();
    private boolean statusAnterior = false;

    public void run() {
        this.carregarArraylist();
        this.iniciarThreads();
        while (true) {
                t1.aguardar();
                System.out.println("Controle");
        }
    }

Assim assim a thread parou mas o run() do controle para no metodo aguardar e fica travado ali.

Ainda é a thread Controle que chama o wait()

Para a outra thread chamar o wait, a linha de execução deve partir do run dela.

Novamente

Thread != objeto.
Thread != classe.

A Control Thread é a linha de execução. Ela roda passo a passo o programa. Imagine seu debugger. Aquela linha verde é a representação da thread. Quando vc chega no aguardar, um step into coloca a mesma thread dentro do método aguardar, e é a mesma thread que chama o wait(). E isso está errado. Quem deveria parar é a linha do depurador que começa no run().

Note que duas threads podem percorrer o mesmo método, ou o mesmo objeto, ao mesmo tempo. Para isso servem as regiões críticas (blocos synchronized).

public class Printer {
	private boolean waiting = false;
	private String texto;
	private PrinterRun pr;
	
	public Printer(String texto)
	{
		this.texto = texto;
		pr = new PrinterRun();
		new Thread(pr).start();
	}
	
	public synchronized void aguardar() {
		waiting = true;
	}
	
	public void continuar() {
		waiting = false;
		synchronized(pr) {
			pr.notify();
		}
	}
	
	public class PrinterRun implements Runnable
	{
		@Override
		public void run() {
			try {
				while (!Thread.interrupted()) {
					while (waiting) {
						synchronized (this) {
							wait(); //Note que essa thread mesmo chama o wait
						}
					}
					System.out.println(texto);
					Thread.sleep(100);
				}
			} catch (InterruptedException e) {
				System.out.println("Caindo fora...");
			}
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		System.out.println("Iniciando threads...");
		Printer p1 = new Printer("1");
		Printer p2 = new Printer("2");
		Printer p3 = new Printer("3");
		Thread.sleep(1000);
		System.out.println("Pausando thread 1");
		p1.aguardar();
		Thread.sleep(1000);
		System.out.println("Pausando thread 2");
		p2.aguardar();
		Thread.sleep(1000);
		System.out.println("Pausando thread 3");
		p3.aguardar();
		Thread.sleep(3000);
		System.out.println("Voltando a imprimir");
		p1.continuar();
		p2.continuar();
		p3.continuar();
		Thread.sleep(1000);
		System.out.println("Finalizando o programa...");
		System.exit(0);
		
	}
}

Valeu Vini,

Estou desenvolvendo uma aplicação para tocar áudio utilizando Java e estava com
grandes problemas com relação as threads de execução e pausa.
Mais uma vez salvou minha vida :smiley: .

Até mais galera.

:slight_smile: