Comprende el código correctamente previamente a adaptarlo a tu proyecto si tquieres aportar algo puedes dejarlo en la sección de comentarios.
Solución:
La solución adecuada a su problema es utilizar una cola de bloqueo. Te da varias ventajas:
- no desperdicia la CPU ocupada esperando
- puede tener una capacidad limitada: imagine que tiene un productor rápido, pero un consumidor lento -> si la cola no tiene un tamaño limitado, entonces su aplicación puede alcanzar fácilmente la condición OutOfMemory
Aquí hay una pequeña demostración con la que puedes jugar:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProdConsTest
public static void main(String[] args) throws InterruptedException
final BlockingQueue queue = new ArrayBlockingQueue<>(10);
final Runnable producer = () ->
for (int i = 0; i < 1000; i++)
try
System.out.println("Producing: " + i);
queue.put(i);
//Adjust production speed by modifying the sleep time
Thread.sleep(100);
catch (InterruptedException e)
//someone signaled us to terminate
break;
;
final Runnable consumer = () ->
while (true)
final Integer integer;
try
//Uncomment to simulate slow consumer:
//Thread.sleep(1000);
integer = queue.take();
catch (InterruptedException e)
//someone signaled us to terminate
break;
System.out.println("Consumed: " + integer);
;
final Thread consumerThread = new Thread(consumer);
consumerThread.start();
final Thread producerThread = new Thread(producer);
producerThread.start();
producerThread.join();
consumerThread.interrupt();
consumerThread.join();
Ahora descomente el sleep()
en el consumidor y observar lo que ocurre con la aplicación. Si estuviera usando una solución basada en un temporizador como la propuesta ScheduledExecutorService
o estabas ocupado esperando, luego con el productor rápido, la cola crecería sin control y eventualmente colapsaría tu aplicación
En lugar de hacer Consumidor extend Runnable
podrías cambiar tu código para incorporar un ScheduledExecutorService
que ejecuta el sondeo de la cola cada medio segundo en lugar de hacer que el hilo duerma. Un ejemplo de esto seria
public void schedule()
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() ->
String str;
try
while ((str = queue.poll()) != null)
call(str); // do further processing
catch (IOException e)
ferpt.felog("svr class", "consumer", "consumer thread", e.getClass().getName() + ": " + e.getMessage());
, 0, 500, TimeUnit.MILLISECONDS);
Aquí tienes las comentarios y valoraciones
Tienes la opción de amparar nuestra faena escribiendo un comentario o dejando una valoración te damos las gracias.