FILÓSOFOS COMENSALES
Veamos el problema.
Érase una vez cinco filósofos que
vivían juntos. La vida de cada filósofo consistía principal-mente en pensar y
comer y, tras años de pensar, todos los filósofos se habían puesto de acuerdo
en que la única comida que contribuía a sus esfuerzos pensadores eran los
espaguetis.
Los preparativos de la comida eran
simples: una mesa redonda en la que había una gran fuente de espaguetis, cinco
platos, uno para cada filósofo y cinco tenedores. Un filósofo que quiera comer
irá a su lugar asignado en la mesa y, usando los dos tenedores de cada lado del
plato, cogerá los espaguetis y se los comerá. El problema es el siguiente:
Inventar un ritual (algoritmo) que permita comer a los filósofos. El algoritmo
debe satisfacer la exclusión mutua (dos filósofos no pueden emplear el mismo tenedor
a la vez), además de evitar el interbloqueo y la inanición
En clase dimos la solución a este problema mediante un algoritmo pero quisimos aportar un poco mas y dejar un código en java que ilustra la solución a este requerimiento.
Creamos una clase llamada controlador
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package filosofos;
/**
*
* @author PERSONAL
*/
public class Controlador {
private static final int pensando = 0;
private static final int hambriento = 1;
private static final int comiendo = 2;
private int n; //numero de filosofos
private int estado[];
public Controlador(int n) {
this.n = n;
estado = new int[n]; //estado del filosofo
}
// EL FILOSOFO id intenta SUS TENEDORES
public synchronized void tomarTenedores(int id) {
estado[id] = hambriento; // establece que tiene hambre
prueba(id);
while (estado[id] != comiendo) // ESPERA x 2 TENEDORES
try { wait();
} catch (Exception e) { System.out.println(e);}
}
// EL FILOSOFO id SUELTA SUS TENEDORES
public synchronized void soltarTenedores(int id) {
int der, izq;
//calcula la posicion a su derecha e izq.
der=(id+1) % n;
izq=id-1;
if (izq<0)
izq=n-1;
estado[id] = pensando;
//checa si alguno está a la espera hambriento
prueba(izq);
prueba(der);
}
//Prueba si los dos filosofos a su lado no estan
//comiendo
public void prueba(int id){
int der, izq;
//calcula la posicion a su derecha e izq.
der=(id+1) % n;
izq=id-1;
if (izq<0)
izq=n-1;
if( estado[id] == hambriento && estado[izq]!= comiendo
&& estado[der]!= comiendo){
estado[id] = comiendo;
notifyAll();
}
}
}
Seguidamente creamos otra llamada filosofo
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package filosofos;
/**
*
* @author PERSONAL
*/
public class Filosofo extends Thread {
private int id;
private Controlador controlador;
private int nComidas;
public Filosofo(int id,Controlador c) {
this.id=id;
controlador=c;
nComidas = 0;
}
//el filosofo pasa un tiempo pensando
public void pensando(){
System.out.println("Filosofo "+id+" pensando");
try {
Thread.sleep((int)(Math.random()*400));
} catch (Exception e) {
System.out.println(e);}
}
//el filosofo toma un tiempo comiendo
public void comer(){
nComidas++;
System.out.println("Filosofo "+id+" comiendo -> Numero comidas:"+nComidas);
try {
Thread.sleep((int)(Math.random()*500));
} catch (Exception e) {
System.out.println(e); }
}
public void run() {
do {
pensando(); //el filosofo pasa un tiempo pensando
controlador.tomarTenedores(id); //intenta tomar tenedores
// Si tiene 2 tenedores;
comer();
controlador.soltarTenedores(id);
} while (true);
}
}
y por ultimo creamos la clase llamada filósofos que es donde daremos uso a nuestro codigo espero les guste y sea de fácil entendimiento
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package filosofos;
/**
*
* @author PERSONAL
*/
public class Filosofos {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Controlador c=new Controlador(5); // 5 FILOSOFOS
Filosofo f[] =new Filosofo[5];
for (int cont=0;cont<5;cont++) {
f[cont]=new Filosofo(cont,c);
f[cont].start();
}
//dejamos pasar un tiempo y terminamos los hilos
try {
Thread.sleep((int)(8000));
} catch (Exception ex1) { System.out.println(ex1);}
System.exit(0);
}
}
muy bueno tu tema
ResponderEliminar