简体   繁体   中英

Best Queue Consumer implementation in Java

Good day!

I want to make an ExecutorService consumers for taking data from queue and working with it on server side. The idea is - I poll queue from time to time and if I see that it is not empty I start ExecutorService with N threads (lets say 5). Then I w8 while queue will be empty and shutdown threads. And all again - poll queue for data.... Is this alg ok? Or may be there are some ready implementations/frameworks for such task?

I found this implementation of ConcurrentQueue cunsumers :

public class ConcurrentQueueClient implements Runnable {

    private Queue<String> concurrentQueue;

    public ConcurrentQueueClient(Queue concurrentQueue) {
        this.concurrentQueue = concurrentQueue;
     }

    public void run() {
         boolean stopCondition = (concurrentQueue.size() == 0);

        while (!stopCondition) {
            for (int i = 0; i < concurrentQueue.size(); i++) {
                System.out.println("Client dequeue item "
                        + concurrentQueue.poll());

            }
            stopCondition = (concurrentQueue.size() == 0);
        }

        System.out.println("Client thread exiting...");
    }
 }

and testing it in such way :

 Queue<String> queue = new ConcurrentLinkedQueue<String>();
 ExecutorService consumers = null;
 while(true) {

if(queue.size() != 0) {
   consumers = Executors.newFixedThreadPool(100);
   for (int i = 0; i < 5; i++) {
        ConcurrentQueueClient client = new ConcurrentQueueClient(queue);
        consumers.execute(client);
   }
}

while (queue.size() != 0) {
       try {
           Thread.sleep(1500);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

}

 consumers.shutdown();
 try {
     consumers.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
 } catch (InterruptedException e) {
     e.printStackTrace();
 }


}

Start over. Wrap your strings in callable or runnable, and queue those to the executor service.

If you have a finite set of data to process, then it's ok to have the main thread calling consumer.shutdown() and consumer.awaitTermination(...) as before, but no sleep loop. If you are going to process indefinitely from the queue, then no shutdown() until the service is.

You will face memory issues too if you don't have a limited blocking queue (nothing to block queue.put()). An ArrayBlockingQueue can be given to the executor service on creation (see ThreadPoolExecutor(...) )

Executor service's threads are doing that check (queue.take()) of the tasks queue by design. Try to avoid polling, it waste CPU. Always try to wait/notify (or await/signal) on conditions from reentrantlocks (which is all taken care of for you in the executor service code)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM