Este ejemplo utiliza la interfaz BlockingQueue
para implementar una cola bloqueante, que es una versión segura para hilos de una cola, adecuada para el escenario de productor-consumidor. La clase LinkedBlockingQueue
es una implementación de BlockingQueue
que utiliza una lista enlazada como estructura de datos interna. Los productores agregan elementos a la cola utilizando put()
y los consumidores los retiran utilizando take()
. La cola se bloqueará automáticamente si está vacía o llena, lo que permite que los hilos esperen de manera segura sin necesidad de sincronización explícita.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class ProducerConsumerExample { public static void main(String[] args) { BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(); Thread producerThread = new Thread(() -> { try { for (int i = 1; i <= 5; i++) { queue.put(i); System.out.println("Productor: Agregó el elemento " + i + " a la cola."); // Simulamos un retraso en la producción Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } }); Thread consumerThread = new Thread(() -> { try { for (int i = 1; i <= 5; i++) { while (queue.isEmpty()) { // Esperar si la cola está vacía System.out.println("Consumidor: La cola está vacía, esperando..."); Thread.sleep(1000); } int element = queue.take(); System.out.println("Consumidor: Retiró el elemento " + element + " de la cola."); } } catch (InterruptedException e) { e.printStackTrace(); } }); // Iniciar los hilos producerThread.start(); consumerThread.start(); // Esperar a que ambos hilos terminen try { producerThread.join(); consumerThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Fin del programa."); } } |