I have to solve the problem below the Philosophers' Dinner, using synchronized
; monitor (Condition, Lock); and creating a Semaphore class with ArrayBlockingQueue
.
The first two I was able to do, now the Semaphore class with ArrayBlockingQueue I could not do.
I did not post the classes solving using Condition, Lock and using synchronized, so as not to deviate from the focus, but basically, they allow the use of the methodsGarfo and largoGarfo by the philosophers without causing a deadlock.
Could anyone help me understand and solve the problem?
FilosofoGlutao class
class FilosofoGlutao implements Runnable {
final int N = 5; // são cinco filosofos e cinco garfos...
public List<Garfo> garfos; // garfos dispon�veis 0, 1, 2, 3 e 4
public final int filosofo;
public FilosofosGlutoes.TSolucao vraSolucao;
FilosofoGlutao(List<Garfo> gs, int fil, FilosofosGlutoes.TSolucao solucao) {
garfos = gs;
filosofo = fil;
this.vraSolucao = solucao;
}
private void executaGarfo(boolean booPega) throws InterruptedException {
switch (vraSolucao.tpSolucaoEnum) {
case SYNCHRONIZED:
if (booPega) {
((SolucaoSynchronized) vraSolucao.vraObject).pegaGarfo(filosofo, garfos.get(filosofo), garfos.get((filosofo + 1) % N));
} else {
((SolucaoSynchronized) vraSolucao.vraObject).largaGarfo(filosofo, garfos.get(filosofo), garfos.get((filosofo + 1) % N));
}
break;
case MONITOR:
if (booPega) {
((SolucaoMonitor) vraSolucao.vraObject).pegaGarfos(filosofo, garfos.get(filosofo), garfos.get((filosofo + 1) % N));
} else {
((SolucaoMonitor) vraSolucao.vraObject).largaGarfos(filosofo, garfos.get(filosofo), garfos.get((filosofo + 1) % N));
}
break;
case SEMAFORO:
if (booPega) {
((SolucaoSemaforo) vraSolucao.vraObject).pegaGarfos(filosofo, garfos.get(filosofo), garfos.get((filosofo + 1) % N));
} else {
((SolucaoSemaforo) vraSolucao.vraObject).largaGarfos(filosofo, garfos.get(filosofo), garfos.get((filosofo + 1) % N));
}
break;
}
}
public void run() {
try {
for (int i = 0; i < 5; i++) {
// pensa ...
pensaMuito(filosofo);
// pega garfos
executaGarfo(true);
comeEspaguete(filosofo);
// larga garfos
executaGarfo(false);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
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 comeEspaguete(int fil) {
System.out.println("@@>" + Thread.currentThread().getName() + " COME ESPAGUETE");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
}
class PhilosophersGlues
public class FilosofosGlutoes {
public enum TSolucaoEnum {
SYNCHRONIZED, MONITOR, SEMAFORO;
}
public static class TSolucao {
public TSolucaoEnum tpSolucaoEnum = TSolucaoEnum.SEMAFORO;
public Object vraObject;
public TSolucao() {
switch (this.tpSolucaoEnum)
{
case SYNCHRONIZED: this.vraObject = new SolucaoSynchronized();
break;
case MONITOR: this.vraObject = new SolucaoMonitor();
break;
case SEMAFORO: this.vraObject = new SolucaoSemaforo();
break;
}
}
}
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);
}
//Solução COM SYNCHRONIZED ->>DESCOMENTAR - Ctrl + Shift + C<<-
//Solução COM MONITOR ->>DESCOMENTAR - Ctrl + Shift + C<<-
TSolucao vraSolucao = new TSolucao();
// cria a thread do filosofo 0
FilosofoGlutao r0 = new FilosofoGlutao(garfos, 0, vraSolucao);
Thread f0 = new Thread(r0);
// cria a thread do filosofo 1
FilosofoGlutao r1 = new FilosofoGlutao(garfos, 1, vraSolucao);
Thread f1 = new Thread(r1);
// cria a thread do filosofo 2
FilosofoGlutao r2 = new FilosofoGlutao(garfos, 2, vraSolucao);
Thread f2 = new Thread(r2);
// cria a thread do filosofo 3
FilosofoGlutao r3 = new FilosofoGlutao(garfos, 3, vraSolucao);
Thread f3 = new Thread(r3);
// cria a thread do filosofo 4
FilosofoGlutao r4 = new FilosofoGlutao(garfos, 4, vraSolucao);
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();
}
}
Fork Class:
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;
}
}