Cena de los filósofos

CLASE PRINCIPAL

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cena_filosofos;

import java.util.concurrent.Semaphore;

/**
 *
 * @author glop
 */
public class Cena_filosofos {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Semaphore[] palillos = new Semaphore[5]; // Se crea el array de semáforos.
       
        // Mediante un bucle for, se recorre el array de semáforos y se le da a cada uno un permiso único de uso.
        for (int c = 0; c < 5; c++) {
            palillos[c] = new Semaphore(1,true);
        }
       
        // Se instancian los cinco filósofos aportando los datos: posiciones de los dos palillos, nombre, y los dos palillos
        // que le pertenecen y actúan como semáforos de uso compartido y excluyente
        filosofo f1 = new filosofo(5,1, "Filósofo 1",palillos[4],palillos[0]);
        filosofo f2 = new filosofo(1,2, "Filósofo 2",palillos[0],palillos[1]);
        filosofo f3 = new filosofo(2,3, "Filósofo 3",palillos[1],palillos[2]);
        filosofo f4 = new filosofo(3,4, "Filósofo 4",palillos[2],palillos[3]);
        filosofo f5 = new filosofo(4,5, "Filósofo 5",palillos[3],palillos[4]);
       
        // Se inician los cinco hilos.
        f1.start();
        f2.start();
        f3.start();
        f4.start();
        f5.start();
       
    }
}

CLASE HILO FILÓSOFO

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cena_filosofos;

// Importo las clases necesarias para trabajar
import java.util.Random;
import java.util.concurrent.Semaphore;

/**
 *
 * @author glop
 */
public class filosofo extends Thread{
  
    private static final Random aleatorio = new Random(); // Generador de números aleatorios
    private Semaphore palilloder; // Semáforo que representa el palillo derecho
    private Semaphore palilloizq; // Semñaforo que representa en palillo izquierdo
    int posder=-1; // Toma la posición del palillo correspondiente para informar al usuario
    int posizq=-1; // Toma la posición del palillo correspondiente para informar al usuario
    String nombre; // Nombre del filósofo
   
    // Construye el filósofo con los datos proporcionados. Éstos son; la posición de los dos palillos que le pertencen.
    // el nombre del filósofo y los dos palillos que utilizará que son semáforos de uso compartido y excluyente 
    public filosofo(int posd,int posiz,String nomb,Semaphore palder,Semaphore palizq) {
        this.posder = posd;
        this.posizq = posiz;
        this.nombre = nomb;
        this.palilloder = palder;
        this.palilloizq = palizq;
    }
   
    // Método que representa al filósofo pensando
    private void pensar() {
       
        try {
         System.out.println(this.nombre + " está pensando");
         sleep(aleatorio.nextInt(5000)) ;  // El tiempo que transcurre pensando se calcula aleatoriamente hasta 5 segundos
        } catch(InterruptedException ex) {
           
        }
    }
   
    // Método que representa al filósofo comiendo
    private void comer() {
      
        try { // Intenta tomar los palillos
           palilloder.acquire(); // Toma el palillo derecho, si este palillo estuviera en uso se entraría en una disputa,
                                 // el hilo se interrumpiría,
                                // y el proceso iría al finally donde lo suelta
          
           if (!palilloizq.tryAcquire()) { // Si el palillo izquierdo esta siendo usado el filósofo espera.
               System.out.println(this.nombre + " está hambriento"); // Se lanza un mensaje por pantalla indicando
                                                                     // que el filósofo está hambriento
              
               return; // Irá inmediatamente al finally donde soltará el palillo derecho que es quien primero tomó
           }
          
           // Si ha llegado hasta aquí es que el palillo izquierdo también ha sido tomado con éxito. ¡Ya puede empezar!
          
           // Se lanza el mensaje por pantalla de que el filósofo ha empezado a comer.
           // También se indica, a efectos informativos, los palillos que utiliza
           System.out.println(this.nombre + " está comiendo con los palillos : " + this.posder + " y " + this.posizq);
           sleep(aleatorio.nextInt(5000)); // Se calcula la demora en comer aleatoriamente hasta 5 segundos
          
           // Se lanza el mensaje por pantalla de que el filósofo ha terminado de comer.
           // También se indica, a efectos informativos, los palillos que ha utilizado y ahora libera       
           System.out.println(this.nombre + " ha terminado de comer y libera los palillos : "+ this.posder + " y " + this.posizq);
           palilloizq.release(); // Como ya ha terminado de comer, suelta el palillo izquierdo.
       } catch (InterruptedException ex) {
          
       } finally {
            // En cualquier caso, soltará el palillo derecho.
           palilloder.release();
       }
    }
   
    @Override
    public void run() {
        while(true) { // En un bucle infinito, piensa y come, piensa y come ...
        pensar();
        comer();
        }
    }
  
}