Problemas com wait() e notifyall()

0 respostas
R

Galera, to fazendo esse trabalho aqui e ele roda legal umas BOOAS vezes , ate que um momento ta dando:

Quinto Exercício

Resolva o problema do Jantar dos Canibais: uma tribo de selvagens come jantares comunitários de uma grande panela de barro que comporta M  porções de missionários e exploradores ensopados. Quando um selvagem que comer, ele se serve de uma porção da panela, a não ser que ela esteja vazia. Se a panela estiver vazia, o selvagem acorda o cozinheiro e então espera até que este tenha reabastecido a panela. Um número arbitrário de threads de selvagens pode executar o seguinte código (sem sincronização):

	while true:
		pegarPorçãoDaPanela();
		comer();

Uma única thread do cozinheiro pode executar o seguinte código (sem sincronização):

	while true:
		colocarPorçõesNaPanela(M);

As restrições de sincronização são:
?	Os selvagens não podem chamar pegarPorçãoDaPanela() se a panela estiver vazia.
?	O cozinheiro  pode chamar colocarPorçõesNaPanela() se a panela estiver vazia.
Adicione código às threads dos selvagens e dos cozinheiros de modo a satisfazer às restrições de sincronização.

Exception:

Cozinheiro depositou na panela, que agora tem:10
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:503)
	at Canibal.run(Canibal.java:19)

RESOLVI O PROBLEMA DA EXCEPTION COLOCANDO UM SYNCRONIZED THIS ANTES DESSE BLOCO, MAS ELE PARA EM CERTO MOMENTO DA EXECUCAO...

Segue o Canibal.java:

public class Canibal extends Thread {
	Buffer Buffer;
	Cozinheiro Cozinheiro;
	
	
	
	public Canibal(Buffer buffer, Cozinheiro Cozinheiro) {
		this.Buffer = buffer;
		this.Cozinheiro = Cozinheiro;
	}



	@Override
	public void run() {
		while (true) {
			while (Buffer.getPorcoes() == 0) {
				try {
					this.wait();
				} catch (InterruptedException e) {
				}
			}
			

			
			if (Buffer.getPorcoes() != 0) {
				synchronized (Cozinheiro) {
				Cozinheiro.notifyAll();	
				}
				Buffer.retira(1);
				System.out.println("Canibal acabou de comer, e a panela tem agora" + Buffer.getPorcoes());
			}
			
			
			
			
		}
		
	}
	
}

Cozinheiro.java:

public class Cozinheiro extends Thread {

	Buffer Buffer;
	int tamanho;

	public Cozinheiro(Buffer Buffer, int tamanho) {
		this.Buffer = Buffer;
		this.tamanho = tamanho;
	}

	public synchronized void run() {
		while (true) {
			
			while (Buffer.getPorcoes() != 0) {
				try {
					this.wait();
				} catch (InterruptedException e) {}				
			}

			if (Buffer.getPorcoes() == 0) {
				Buffer.deposita(tamanho);
				System.out.println("Cozinheiro depositou na panela, que agora tem:" + Buffer.getPorcoes());
			}
			
			
		}
	}
}

Buffer.java

public class  Buffer {

	int porcoes;
	
	public Buffer() {};
	
	public int getPorcoes() {
		return porcoes;
	}

	public void setPorcoes(int porcoes) {
		this.porcoes = porcoes;
	}
	
	public synchronized void retira(int num) {
		this.porcoes = this.porcoes - num;
	}
	
	public synchronized void deposita (int num) {
		this.porcoes = this.porcoes + num;	
	}
	
	
}

Principal.java

public class Principal {
	public static void main(String[] args) {
		int tamanho = 10;
		Buffer Buffer = new Buffer();
		Cozinheiro Cooker = new Cozinheiro(Buffer, tamanho);
		Canibal Eater = new Canibal(Buffer, Cooker);
		
		Cooker.start();
		Eater.start();
	
	}
}

Eu acho que poderia usar o Buffer como monitor, so que tentei, tentei e nao consegui, o melhor que saiu foi ate agora :p

Criado 18 de setembro de 2011
Respostas 0
Participantes 1