Clase Java.util.concurrent.Semaphore en Java

Un semáforo controla el acceso a un recurso compartido mediante el uso de un contador. Si el contador es mayor que cero, se permite el acceso. Si es cero, se deniega el acceso. Lo que está contando el contador son permisos que permiten el acceso al recurso compartido. Por lo tanto, para acceder al recurso, un subproceso debe recibir un permiso del semáforo.

Sintaxis:

public class Semaphore
extends Object
implements Serializable

Conceptualmente, un semáforo mantiene un conjunto de permisos. Cada adquisición() bloquea si es necesario hasta que haya un permiso disponible y luego lo toma. Cada liberación() agrega un permiso, potencialmente liberando a un adquirente de bloqueo. Sin embargo, no se utilizan objetos de permisos reales; el semáforo simplemente lleva la cuenta del número disponible y actúa en consecuencia. 

Métodos de la clase Semaphore 

Método Acción realizada
adquirir() Adquiere un permiso, si hay uno disponible y regresa inmediatamente, reduciendo el número de permisos disponibles en uno. Si el subproceso actual se interrumpe mientras espera un permiso, se lanza InterruptedException
adquirir (permisos int) Adquiere el número dado de permisos, si están disponibles, y regresa inmediatamente, reduciendo el número de permisos disponibles en la cantidad dada. Si el subproceso actual se interrumpe mientras espera un permiso, se lanza una InterruptedException.
adquirir ininterrumpidamente() Adquiere un permiso si hay uno disponible y regresa inmediatamente, reduciendo el número de permisos disponibles en uno. Si el subproceso actual se interrumpe mientras espera un permiso, continuará esperando. 
adquirir ininterrumpidamente (permisos int) Dado un número de permisos, si están disponibles, y regresa inmediatamente, reduciendo el número de permisos disponibles por la cantidad dada. Si el subproceso actual se interrumpe mientras espera un permiso, continuará esperando.
permisos disponibles() Devuelve el número actual de permisos disponibles en este semáforo. Este método se suele utilizar con fines de depuración y prueba. 
drenajePermisos() Adquiere y devuelve todos los permisos que están inmediatamente disponibles. 
obtenerLongitudCola() Devuelve una estimación del número de subprocesos que esperan adquirir. El valor es solo una estimación porque la cantidad de subprocesos puede cambiar dinámicamente mientras este método atraviesa estructuras de datos internas. Este método está diseñado para monitorear el estado del sistema, no para controlar la sincronización. 
getQueuedThreads() Devuelve una colección que contiene subprocesos que pueden estar esperando para adquirir. Debido a que el conjunto real de subprocesos puede cambiar dinámicamente mientras se construye este resultado, la colección devuelta es solo una estimación del mejor esfuerzo. Los elementos de la colección devuelta no están en ningún orden en particular
tiene subprocesos en cola() Consulta si hay subprocesos esperando para adquirir. Tenga en cuenta que debido a que las cancelaciones pueden ocurrir en cualquier momento, una verdadera devolución no garantiza que algún otro subproceso adquiera alguna vez. Este método está diseñado principalmente para monitorear el estado del sistema. 
es justo() Devuelve verdadero si este semáforo tiene equidad establecida como verdadero. 
probarAdquirir() Adquiere un permiso, si hay alguno disponible y lo devuelve inmediatamente, con el valor verdadero, reduciendo en uno el número de permisos disponibles. Si no hay ningún permiso disponible, este método regresará inmediatamente con el valor falso.
 reducePermits(int reducción) Reduce el número de permisos disponibles en la reducción indicada. Este método puede ser útil en subclases que usan semáforos para rastrear recursos que dejan de estar disponibles. Este método se diferencia de la adquisición en que no bloquea la espera de que los permisos estén disponibles. 
liberar() Libera un permiso, aumentando el número de permisos disponibles en uno. Si algún subproceso está tratando de adquirir un permiso, entonces se selecciona uno y se le otorga el permiso que se acaba de publicar. 
liberación (permisos int) Libera el número dado de permisos, aumentando el número de permisos disponibles en esa cantidad. Si algún subproceso está tratando de adquirir permisos, entonces se selecciona uno y se le otorgan los permisos que se acaban de publicar. Si el número de permisos disponibles satisface la solicitud de ese subproceso, entonces ese subproceso se (re)habilita para propósitos de programación de subprocesos; de lo contrario, el subproceso esperará hasta que haya suficientes permisos disponibles. 
tryAcquire(int permisos) Adquiere el número dado de permisos, si están disponibles, y regresa inmediatamente, con el valor verdadero, reduciendo el número de permisos disponibles por la cantidad dada. Si no hay suficientes permisos disponibles, este método regresará inmediatamente con el valor falso.
tryAcquire (tiempo de espera prolongado, unidad TimeUnit) Adquiere un permiso si hay uno disponible y regresa inmediatamente, con el valor verdadero, reduciendo el número de permisos disponibles en uno. Si transcurre el tiempo de espera especificado, se devuelve el valor falso. Si el tiempo es menor o igual a cero, el método no esperará nada. 
tryAcquire (permisos int, tiempo de espera prolongado, unidad TimeUnit) Adquiere el número dado de permisos, si están disponibles, y regresa inmediatamente, con el valor verdadero, reduciendo el número de permisos disponibles por la cantidad dada. Si transcurre el tiempo de espera especificado, se devuelve el valor falso. Si el tiempo es menor o igual a cero, el método no esperará nada. Todos los permisos que debían asignarse a este subproceso, en su lugar, se asignan a otros subprocesos que intentan adquirir permisos. 
Enstringr() Devuelve una string que identifica este semáforo, así como su estado. El estado, entre paréntesis, incluye la string «Permisos =» seguida del número de permisos.

Ejemplo: la salida no será la misma en cada ejecución.

Java

// Java program to demonstrate
// methods of Semaphore class
import java.util.concurrent.*;
  
class MyThread extends Thread {
    Semaphore sem;
    String threadName;
    public MyThread(Semaphore sem, String threadName)
    {
        super(threadName);
        this.sem = sem;
        this.threadName = threadName;
    }
  
    @Override public void run()
    {
  
        // First, get a permit.
        System.out.println(threadName
                           + " is waiting for a permit.");
  
        try {
            // acquire method
            sem.acquire();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
  
        System.out.println(threadName + " gets a permit");
  
        // Now, critical section
        // other waiting threads will wait, until this
        // thread release the lock
        for (int i = 0; i < 2; i++) {
            // hasQueuedThreads() methods
            boolean b = sem.hasQueuedThreads();
            if (b)
                // getQueuedLength() methods
                System.out.println("Length of Queue : "
                                   + sem.getQueueLength());
  
            // Now, allowing a context switch -- if
            // possible.
            try {
                Thread.sleep(10);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
  
        // Release the permit.
        System.out.println(threadName
                           + " releases the permit.");
  
        // release() method
        sem.release();
    }
}
  
// Driver class
public class SemaphoreDemo {
  
    public static void main(String args[])
        throws InterruptedException
    {
        // creating a Semaphore object
        // with number of permits 3 and fairness true
        Semaphore sem = new Semaphore(3, true);
  
        // isFair() method
        System.out.println("is Fairness enabled : "
                           + sem.isFair());
  
        // Main thread try to acquire 2 permits
        // tryAcquire(int permits) method
        sem.tryAcquire(2);
  
        // availablePermits() method
        System.out.println("Available permits : "
                           + sem.availablePermits());
  
        // drainPermits() method
        System.out.println(
            "number of permits drain by Main thread : "
            + sem.drainPermits());
  
        // permit released by Main thread
        sem.release(1);
  
        // creating two threads with name A and B
        MyThread mt1 = new MyThread(sem, "A");
        MyThread mt2 = new MyThread(sem, "B");
  
        // starting threads A
        mt1.start();
  
        // starting threads B
        mt2.start();
  
        // toString method
        System.out.println(sem.toString());
  
        // waiting for threads A and B
        mt1.join();
        mt2.join();
    }
}

Producción:

is Fairness enabled : true
Available permits : 1
number of permits drain by Main thread : 1
java.util.concurrent.Semaphore@5b6f7412[Permits = 1]
A is waiting for a permit.
A gets a permit
B is waiting for a permit.
Length of Queue : 1
A releases the permit.
B gets a permit
B releases the permit.

Este artículo es una contribución de Gaurav Miglani. Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org . Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *