Semaphore

http://slides.com/uesteibar/semaphore/live

¿Qué es?

La clase Semaphore se utiliza para restringir el número de hilos que pueden acceder a algunos recursos.

¿Por qué?

Para facilitar la programación de aplicaciones complejas, a partir de la versión 5 de Java se creó un nuevo paquete de datos java.util.concurrent donde aparecen clases de más alto nivel.

¿Cómo? (1/4)

API

  • Constructores:
    • Semaphore(int permits)
       
  • Métodos:
    • acquire();
    • release();

¿Cómo? (2/4)

public static void main(String[] args) {
        
        // Un semáforo de conteo.
        // Conceptualmente, mantiene un conjunto de permisos.
        //
        Semaphore semaphore = new Semaphore(0);
        
        Saludo t1 = new Saludo(1, semaphore);
        Saludo t2 = new Saludo(2, semaphore);
        Saludo t3 = new Saludo(3, semaphore);

        t1.start();
        t2.start();
        t3.start();
        try {
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException e) {
            System.out.println(
                    "Hilo principal del proceso interrumpido.");
        }
        System.out.println(
                "Proceso acabando.");
    }

¿Cómo? (3/4)

import java.util.concurrent.Semaphore;
class Saludo extends Thread {

    private Semaphore sem;
    private int id;

    Saludo(int orden, Semaphore s) {
        this.id = orden;
        this.sem = s;
    }
    // Necesitamos saber cuántos hilos atacarán el recurso. Al final no queda ningún permiso abierto.
    public void run() {        
        if (id == 1 || id == 3) {
            try {        
                // Cada adquire() se bloquea, hasta que un permiso esté disponible.                
                sem.acquire();
            
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally{
              //Cada release() añade un permiso, lo que podría liberar un adquire() bloqueado. 
              // sem.release();
            }
        }
        System.out.println("Hola, soy el thread" + id);
        if (id == 2) { 
            sem.release();
            sem.release();
        }
    }
}
import java.util.concurrent.Semaphore;
class Saludo extends Thread {

    private Semaphore sem;
    private int id;

    Saludo(int orden, Semaphore s) {
        this.id = orden;
        this.sem = s;
    }
    //Independientemente de cuantos hilos ataquen el recurso, lo harán de manera ordenada. Al final queda un permiso abierto.
    public void run() {        
        if (id == 1 || id == 3) {
            try {        
                // Cada adquire() se bloquea, hasta que un permiso esté disponible.                
                sem.acquire();
            
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally{
              //Cada release() añade un permiso, lo que podría liberar un adquire() bloqueado. 
              sem.release();
            }
        }
        System.out.println("Hola, soy el thread" + id);
        if (id == 2) { 
            //sem.release();
            sem.release();
        }
    }
}

¿Cómo? (4/4)

Código fuente:

Semaphore API (Java)

By uesteibar

Semaphore API (Java)

  • 1,362