En Java, utilizamos el semáforo en la sincronización de hilos. Se utiliza para controlar el acceso a un recurso compartido que utiliza una variable de contador. Java también proporciona una clase Semaphore que contiene constructores y varios métodos para controlar el acceso sobre el recurso compartido. Lo discutiremos más adelante en esta sección.

Antes de avanzar en esta sección, primero, entenderemos qué es semáforo, tipos de semáforo, cómo funciona, y cómo implementar semáforo. Después de conocer todo esto, pasaremos a los programas Java semaphore.

¿Qué es un semáforo?

Un Semaphore se utiliza para limitar el número de hilos que quieren acceder a un recurso compartido. En otras palabras, es una variable no negativa que se comparte entre los hilos conocida como contador. Establece el límite de los hilos. Un mecanismo en el que un hilo está esperando en un semáforo puede ser señalado por otros hilos.

  • Si el contador > 0, el acceso a los recursos compartidos se proporciona.
  • Si el contador = 0, el acceso a los recursos compartidos se niega.

En resumen, el contador mantiene el seguimiento del número de permisos que ha dado a un recurso compartido. Por lo tanto, semáforo concede permiso a los hilos para compartir un recurso.

Características de Semáforo

Hay las siguientes características de un semáforo:

  • Proporciona sincronización entre los hilos.
  • Disminuye el nivel de sincronización. Por lo tanto, proporciona un mecanismo de sincronización de bajo nivel.
  • El semáforo no contiene un valor negativo. Mantiene un valor que puede ser mayor que cero o igual a cero.
  • Podemos implementar el semáforo utilizando la operación de prueba e interrupciones, y utilizamos los descriptores de archivo para ejecutarlo.

Funcionamiento del Semáforo

El semáforo controla sobre el recurso compartido a través de una variable contador. El contador es un valor no negativo. Contiene un valor mayor que 0 o igual a 0.

  • Si el contador > 0, el hilo obtiene permiso para acceder al recurso compartido y el valor del contador se decrementa en 1.
  • Si no, el hilo será bloqueado hasta que se pueda adquirir un permiso.
  • Cuando la ejecución del hilo se completa entonces no hay necesidad del recurso y el hilo lo libera. Después de liberar el recurso, el valor del contador se incrementa en 1.
  • Si otro hilo está esperando para adquirir un recurso, el hilo adquirirá un permiso en ese momento.
  • Si el contador = 0, el hilo no obtiene permiso para acceder al recurso compartido.

Entendamos el funcionamiento del semáforo con la ayuda de un diagrama de flujo.

Semáforo de Java

Tipos de Semáforos

Hay cuatro tipos de semáforos, que son los siguientes:

  • Semáforos de conteo
  • Semáforos limitados
  • Semáforos temporizados
  • Semáforos binarios

Semáforo de Java

Discutiremos uno por uno en detalle.

Semáforos de conteo

Los semáforos de conteo se utilizan para resolver la situación en la que más de un proceso quiere ejecutarse en la sección crítica, simultáneamente. Por lo tanto, para superar este problema utilizamos semáforos de conteo. Por ejemplo, considera el siguiente fragmento de código.

Veamos la implementación de los semáforos de conteo.

CountingSemaphoresExample.java

Semáforos acotados

Podemos establecer el límite superior utilizando los semáforos acotados. Se utiliza en lugar de los semáforos de conteo porque los semáforos de conteo no contienen ningún valor de límite superior. El valor del límite superior denota cuántas señales puede almacenar. Por ejemplo, considere el siguiente fragmento de código.

Veamos la implementación del semáforo acotado.

BoundedSemaphoresExample.java

Semáforos temporizados

Los semáforos temporizados permiten que un hilo se ejecute durante un período de tiempo determinado. Después de un tiempo determinado, el temporizador se reinicia y libera todos los demás permisos.

Veamos la implementación de los semáforos temporizados.

TimedSemaphoresExample.java

Semáforos binarios

Los semáforos binarios son los mismos que los semáforos de conteo. Pero recuerda que sólo acepta valores binarios ya sea 0 o 1. Su implementación es sencilla en comparación con otros semáforos. Si el valor es 1, la operación de la señal es un éxito, falla en caso contrario.

Veamos la implementación de los semáforos binarios.

BinarySemaphoresExample.java

Semaphore en Java

En Java, es una construcción de sincronización de hilos. La construcción utiliza una variable conocida como contador que controla el acceso sobre el recurso compartido. Es un tipo de variable que se utiliza para gestionar procesos concurrentes y también sincronizarlos. También se utiliza para evitar condiciones de carrera. Restringe el número de hilos para acceder a un recurso compartido.

Por ejemplo, podemos restringir un archivo para acceder hasta 10 conexiones simultáneamente.

Clase Semaphore de Java

Java proporciona una clase Semaphore para implementar el mecanismo de semáforo. Pertenece al paquete java.util.concurrent. Implementa la interfaz Serializable. Por lo tanto, la implementación manual no es necesaria.

La clase Semaphore proporciona los siguientes dos constructores:

  • Semaphore(int permits)
  • Semaphore(int permits, boolean fair)

Semaphore(int permits)

Crea un Semaphore y analiza el número de permisos (número inicial de permisos disponibles) como argumento. Especifica el número de hilos que pueden compartir un recurso a la vez. El valor de los permisos puede ser negativo. En tal caso, debe producirse una liberación antes de que se conceda cualquier adquisición.

Sintaxis:

Semaphore(int permits, boolean fair)

Crea un Semaphore con el número de permisos y la configuración de fairness dados.

Sintaxis:

Percibe dos parámetros:

  • permits: El valor de los permisos puede ser negativo. En tal caso, la liberación debe producirse antes de que se conceda ninguna adquisición.
  • fair: Si establecemos el valor a true, el semáforo garantiza FIFO a los hilos en el orden en que se solicitan, false Por defecto, todos los hilos que están esperando el recurso conceden permisos en un orden indefinido.

Métodos de la clase Semaphore

La clase proporciona los siguientes métodos:

Método acquire(): El método adquiere los permisos del semáforo, bloqueando hasta que haya uno disponible, o se interrumpa el hilo. Reduce el número de permisos disponibles en 1.

Si no hay ningún permiso disponible para el hilo actual, el hilo pasa a estar desactivado a efectos de programación de hilos. El hilo actual va en el estado inactivo hasta que una de las dos cosas sucede:

  • Si el otro hilo invoca el método release() para liberar el recurso entonces el hilo actual obtiene permisos.
  • Si el otro hilo interrumpe el hilo actual.

Lanza InterruptedException si el hilo actual es interrumpido. El método no devuelve ningún valor.

Sintaxis:

Método Release(): Libera un permiso y lo devuelve al semáforo. Incrementa el número de permisos disponibles en 1. Si un hilo intenta adquirir un permiso, el semáforo concede el permiso para adquirir el recurso que acaba de ser liberado por otros hilos. Además, ese hilo es considerado para propósitos de programación de hilos.

Sintaxis:

MétodoPermisosDisponibles(): El método devuelve el número de permisos disponibles en el semáforo para conceder el recurso. Por lo general, se utiliza para fines de depuración y pruebas.

Sintaxis:

Entendamos los métodos anteriores a través de un simple ejemplo.

Usando Semáforo como Bloqueo

Java nos permite utilizar un semáforo como un bloqueo. Es decir, bloquea el acceso al recurso. Cualquier hilo que quiera acceder al recurso bloqueado, debe llamar al método acquire() antes de acceder al recurso para adquirir el bloqueo. El hilo debe liberar el bloqueo llamando al método release(), después de la finalización de la tarea. Recuerda que el límite superior es 1. Por ejemplo, considere el siguiente fragmento de código:

Veamos un ejemplo de semáforo y usemos el semáforo como bloqueo.

SemaphoreAsLock.java

Salida:

Semáforo de Java

Nota: Cuando ejecutamos el programa anterior, obtenemos una salida diferente cada vez. Por lo tanto, su salida puede diferir de la salida mostrada arriba.

Ejemplo de Semáforo en Java

Vamos a entender el mecanismo de semáforo a través de un programa en Java. En el siguiente ejemplo, hemos creado un constructor de la clase Semaphore con el valor inicial de permiso 3.

SemaphoreExample.java

Salida:

Java Semaphore

Deja una respuesta

Tu dirección de correo electrónico no será publicada.