Java: Thread producer consumer what is the most efficient way to wait for data to be produced

陌路散爱 提交于 2019-12-05 06:37:45
John Vint

what is the most efficient way to wait for data to be produced

The BlockingQueue has blocking functionality which will suspend threads waiting for a queue to be not empty or not full. In your case you are spinning on the queue which consume CPU. This is not preferred.

You should use take.

Suspending retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

BlockingQueue#take

This will be the most efficient way to wait for elements from a queue as suspending threads consume no cpu. Once a new item is put on the queue the waiting threads will be woken.

Then you can use put which has the same waiting semantics as take but only if the queue is not full.

public void run(){
   LocalTime timestamp = null;
   while((timestamp = data.take()) != null){
      ...
   }
}

Updating based on our comments:

But in this case the timestamps are created in a sequential order and added. But a timestamp may be less in the future. E.g. Head node is 2 mins in future, Second node is 1 min, so the second node wants processing first

Then my follow up:

So you need priority queuing based on the timestamp of the LocalDate?

Not sure if you are using the LocalDate from JodaTime or Java 8, let's assume the latter.

You can use a PriorityBlockingQueue with the same blocking semantics. However, the priority aspect of a BlockingQueue will enqueue elements based on whatever order is defined. In your case, using the LocalDate you can have elements ordered from oldest-to-youngest or youngest-to-oldest.

BlockingQueue<LocalDate> data = new PriorityBlockingQueue<>(); 

OR INVERSE THE ORDER

BlockingQueue<LocalDate> data = new PriorityBlockingQueue<>(0, (a,b) -> b.compareTo(a));

In this case, you will process LocalDate in their natural order and not the order in which they are enqueued.

If you are using JodaTime's LocalDate you may need to implement your own Comparator similar to my second example.

EDIT: just realized you had this tagged as java-7. So you will use the JodaTime and if the JodaTime LocalDate does not implement Comparable, just create your own.

Firt you need to use the take method. This method will block while the queue is empty. THis will replace your check to see if the queue is empty.

Second, why do you need a timestamp? If the timestamp is to make sure you process the requests int he order that they were put into the queue then you do not need it, as the queue is FIFO and made for concurrent multithreaded environment. If the timestamp is from outside of the system, some external timestamp, where the requests might come out of order but then need to be processed in order, then this BlockQueue will not cut it. You might need a PriorityBlockingQueue where you will prioritize the requests by timestamp. So either get rid of the timestamp or use a PriorityBlockingQueue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!