Esta vez, cambian básicamente tres cosas:
Primero, ya no son tenedores, porque me pareció ridiculo que necesitaces dos tenedores para comer, así que lo cambié por palillos. Tiene sentido, ¿no?
Segundo, guardo los palillos a los que accede cada comensal en una matriz de enteros, donde por defecto el primer valor será el numero de identificación del comensal, y el segundo será 0 o 1, para cada palillo.
Tercero, SEMAFOROS. ¿por qué? Porque me dejo de preocupar por que se mezclen los permisos para tomar los palillos. En mi programa anterior, eran dos sentencias diferentes la que revisa la disponibilidad de los tenedores, y la que efectúa el cambio de disponibilidad, por lo que si dos hilos accedían casi al mismo tiempo a la revisión, era posible que uno de ellos tomara los tenedores e inmediatamente después el otro también, y luego ambos "reportaban" que los tenedores estaban tomados, y luego, muy cinicamente, se ponían a comer. Además así puedo especificar que solo un comensal puede sostener cada palillo.
Oh y también volví aleatorios los tiempos de retardo, porque noté que hay menos problemas así.
Ignoro la razón de esto último.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.concurrent.Semaphore; | |
public class ejemplo2 extends Thread { | |
private final int id; | |
private final Semaphore[] semaforo; | |
private final int[][] palillos; | |
private final int palilloL; | |
private final int palilloR; | |
// private int hambre=5; | |
public ejemplo2(int id, Semaphore[] semaforo, int[][] palillos){ | |
this.id=id; | |
this.semaforo=semaforo; | |
this.palillos=palillos; | |
this.palilloL=palillos[id][0]; | |
this.palilloR=palillos[id][1]; | |
} | |
protected void comer(){ | |
if(semaforo[palilloR].tryAcquire()){ | |
if(semaforo[palilloR].tryAcquire()){ | |
System.out.println("FILÓSOFO " + id + " ESTÁ COMIENDO. USA LOS PALILLOS "+palilloL+" Y "+palilloR); | |
// hambre--; | |
try{ | |
int time=0; | |
while(time<=0) | |
time=new Random().nextInt()%2000; | |
sleep(time); | |
}catch (InterruptedException ex){ | |
System.out.println("Error : " + ex.toString()); | |
} | |
System.out.println("Filósofo " + id + " terminó de comer. Liberó los palillos " + palilloL + " y " + palilloR); | |
semaforo[palilloR].release(); | |
} | |
semaforo[palilloL].release(); | |
}else{ | |
System.out.println("Filósofo " + id + " está hambriento."); | |
} | |
} | |
protected void pensar(){ | |
System.out.println("Filósofo " + id + " está pensando."); | |
try{ | |
int time=0; | |
while(time<=0) | |
time=new Random().nextInt()%2000; | |
sleep(time); | |
}catch(InterruptedException ex){ | |
System.out.println("Error en el método pensar(): " + ex.toString()); | |
} | |
} | |
@Override | |
public void run(){ | |
while(true){ | |
pensar(); | |
comer(); | |
// if(hambre<=0){ | |
// System.out.println("Filosofo "+id+" está satisfecho"); | |
// break; | |
// } | |
} | |
} | |
} |
En la siguiente clase notarán como cree la matriz de la que hablé antes. La gran diferencia en este caso con respecto a mi intento anterior, es que ya solo creo los 5 comensales, y ellos mismos funcionan como buffers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package filosofos; | |
import java.util.concurrent.Semaphore; | |
public class ejemplo1 { | |
final static int nFilosofos = 5; | |
final static int[][] palillos = { | |
{0, 4}, // filosofo 0 | |
{1, 0}, // filosofo 1 | |
{2, 1}, // filosofo 2 | |
{3, 2}, // filosofo 3 | |
{4, 3} // filosofo 4 | |
}; | |
final static Semaphore[] semaforo=new Semaphore[nFilosofos]; | |
public static void main(String[] args){ | |
for (int i = 0; i < nFilosofos; i++){ | |
semaforo[i]=new Semaphore(1); | |
} | |
for(int idFilosofo=0; idFilosofo<nFilosofos; idFilosofo++){ | |
new ejemplo2(idFilosofo, semaforo, palillos).start(); | |
} | |
} | |
} |
Y solo para que quede claro, sigo sin usar sincronización.
No hay comentarios:
Publicar un comentario