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 só 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