Problema do jantar dos filósofos
Cinco filósofos tem um prato de espaguete. O espaguete está tão escorregadio que um filósofo precisa de dois garfos para comê-lo. Entre cada par de pratos está um garfo.
A vida de um filósofo consiste em alternar período de comer e pensar. Quando uma filósofa fica fome, ela tenta pegar os garfos à sua direita e à sua esquerda, um de cada vez em qualquer ordem. Se conseguir pegar dois garfos, ela comerá durante um determinado tempo e, então, colocará os garfos na mesa novamente e continuará a pensar. A questão fundamental é: você consegue escrever um programa para cada filósofo que faça o que deve fazer e nunca trave?
Tanenbaum, Andrew S.
Bom têm que resolver o problema de duas formas, a primeira é essa:
[já funcionando]
[code]package jantarFilosofico;
public class Garfo {
private int idGarfo;
private boolean estadoGarfo;
private int dono;
public Garfo(int id){
idGarfo = id;
estadoGarfo = false; // desocupado
dono = -1; // sem dono
}
public int getIdGarfo(){
return idGarfo;
}
public void setIdGarfo(int g){
idGarfo = g;
}
public int getDonoGarfo(){
return dono;
}
public void setDonoGarfo(int d){
dono = d;
}
public boolean getEstadoGarfo(){
return estadoGarfo;
}
public void setEstadoGarfo(boolean ocupado){
estadoGarfo = ocupado;
}
}
[/code]
[code]package jantarFilosofico;
import java.util.List;
import jantarFilosofico.Garfo;
class Filosofo implements Runnable {
final int N = 5; // são cinco filosofos e cinco garfos…
List garfos; // garfos disponíveis 0, 1, 2, 3 e 4
int filosofo;
Filosofo (List gs, int fil){
garfos = gs;
filosofo = fil;
}
public void run(){
for (int i=0; i<5; i++){
// pensa ...
pensaMuito(filosofo);
// pega garfo da esquerda
pegaGarfo(/*posiçao*/filosofo, /*dono*/filosofo);
// pega garfo da direita
pegaGarfo(/*posiçao*/(filosofo+1)%N, /*dono*/filosofo);
// fatura o espaguete
comeEspaguete(filosofo);
// larga o garfo da esquerda
largaGarfo(/*posiçao*/filosofo, /*dono*/filosofo);
// larga o garfo da direita
largaGarfo(/*posiçao*/(filosofo+1)%N, /*dono*/filosofo);
}
}
private void pensaMuito(int fil){
switch (fil) {
case 0: // filosofo 0 pensa por 1000 ms...
try{
System.out.println("!!>"+Thread.currentThread().getName()+" PENSA");
Thread.sleep(500);}
catch (InterruptedException e){}
case 1: // filosofo 1 pensa por 2000 ms...
try{
System.out.println("!!>"+Thread.currentThread().getName()+" PENSA");
Thread.sleep(1000);}
catch (InterruptedException e){}
case 2: // filosofo 1 pensa por 3000 ms...
try{
System.out.println("!!>"+Thread.currentThread().getName()+" PENSA");
Thread.sleep(1500);}
catch (InterruptedException e){}
case 3: // filosofo 1 pensa por 4000 ms...
try{
System.out.println("!!>"+Thread.currentThread().getName()+" PENSA");
Thread.sleep(2000);}
catch (InterruptedException e){}
case 4: // filosofo 1 pensa por 5000 ms...
try{
System.out.println("!!>"+Thread.currentThread().getName()+" PENSA");
Thread.sleep(2500);}
catch (InterruptedException e){}
}
}
private void pegaGarfo(int pos, int dono){
if (((Garfo)garfos.get(pos)).getEstadoGarfo()==false){ // desocupado
System.out.println("++>"+Thread.currentThread().getName()+" PEGA GARFO "+ pos);
((Garfo)garfos.get(pos)).setEstadoGarfo(true); // pega garfo
((Garfo)garfos.get(pos)).setDonoGarfo(dono); // pega garfo
}
}
private void largaGarfo(int pos, int dono){
if (((Garfo)garfos.get(pos)).getEstadoGarfo()==true &&
((Garfo)garfos.get(pos)).getDonoGarfo() == dono){ // desocupado
System.out.println("-->"+Thread.currentThread().getName()+" LARGA GARFO "+ pos);
((Garfo)garfos.get(pos)).setEstadoGarfo(false); // garfo liberado
((Garfo)garfos.get(pos)).setDonoGarfo(-1); // garfo sem dono
}
}
private void comeEspaguete(int fil){
// se ambos os garfos estiverem reservados pelo
// filosofo "fil", então ele come espaguete...
// Testar a sua solução de proteção, comente o if, deixando apenas o
// seu conteúdo liberado
if (((Garfo)garfos.get(fil)).getEstadoGarfo() &&
((Garfo)garfos.get((fil+1)%N)).getEstadoGarfo() &&
((Garfo)garfos.get(fil)).getDonoGarfo()==fil &&
((Garfo)garfos.get((fil+1)%N)).getDonoGarfo()==fil){
System.out.println("@@>"+Thread.currentThread().getName()+" COME ESPAGUETE");
try{ Thread.sleep(5000);}
catch (InterruptedException e){}
}
}
}
[/code]
[code]package jantarFilosofico;
import java.util.ArrayList;
import java.util.List;
import jantarFilosofico.Garfo;
public class JantarMain {
public static void main(String[] args) {
// cria os grafos (coleção de 5 garfos)
List<Garfo>garfos = new ArrayList<Garfo>();
for (int i = 0; i<=4; i++){
Garfo garfo = new Garfo(i);
garfos.add(i,garfo);
}
// cria a thread do filosofo 0
Filosofo r0 = new Filosofo(garfos, 0);
Thread f0 = new Thread(r0);
// cria a thread do filosofo 1
Filosofo r1 = new Filosofo(garfos, 1);
Thread f1 = new Thread(r1);
// cria a thread do filosofo 2
Filosofo r2 = new Filosofo(garfos, 2);
Thread f2 = new Thread(r2);
// cria a thread do filosofo 3
Filosofo r3 = new Filosofo(garfos, 3);
Thread f3 = new Thread(r3);
// cria a thread do filosofo 4
Filosofo r4 = new Filosofo(garfos, 4);
Thread f4 = new Thread(r4);
// nomeia as threads
f0.setName("F0");
f1.setName("F1");
f2.setName("F2");
f3.setName("F3");
f4.setName("F4");
// manda as threads pra fila de pronto
f0.start();
f1.start();
f2.start();
f3.start();
f4.start();
}
}
[/code]
A segunda é com synchronized, que é onde não estou conseguindo fazer, se alguém puder me ajuda agradeço.