0

I was going through the javadocs and source code for drainTo method present in BlockingQueue interface and LinkedBlockingQueue implementation of the same. My understanding of this method after looking at the source (JDK7), is that the calling thread actually submits a Collection and afterwards acquires a takeLock(), which blocks other consumers. After that till the count of max elements, the items of the nodes are removed from the queue and put in a collection.

What I could appreciate is that it saves the threads from acquiring locks again and again, but pardon my limited knowledge, I could not appreciate the need for the same in real world examples. Could some one please share some real world examples where drainTo behavior is observable ?

userx
  • 3,713
  • 5
  • 32
  • 38
  • 1
    Let's say you store dishes prepared by cooks of a self-service restaurant in a blocking queue, waiting for customers to take them out of the queue. And let's say the restaurant closes its doors at the end of the day. You might want to remove all the remaining dishes from the queue and store them in a fridge. – JB Nizet Feb 16 '14 at 08:09
  • @JBNizet- You mean in such a case an owner thread can poll the dishes on the queue by taking a lock , which is not only used to block the other customers, but also in literal terms act as a happens before construct, so that all the dishes put on the queue in the latest state are retrieved and then put in a fridge ? – userx Feb 16 '14 at 08:20
  • @JBNizet - So essentially we would need that functionality while the application prepares to shut it down. Could you give me another example wherein it is being used during the peak hours of a restaurant ? – userx Feb 16 '14 at 08:22
  • 2
    I'm not saying this is the unique case, and not even this is the most frequent case. I just imagined one case where it could be used. You could imagine a schedules executor service to drain the queue at regular intervals, for example. – JB Nizet Feb 16 '14 at 08:26

1 Answers1

1

Well, I used it in real life code and it looked quite natural to me: a background database thread creates items and puts them into a queue in a loop until either the end of data is reached or a stop signal is detected. On the first item a UI updater is launched using EventQueue.invokeLater. Due to the asynchronous nature and some overhead in this invokeLater mechanism, it will take some time until the UI updater comes to the point where it queries the queue and most likely more than one item may be available.

So it will use drainTo to get all items that are available at this specific point and update a ListDataModel which produces a single event for the added interval. The next update can be triggered using another invokeLater or using a Timer. So drainTo has the semantic of “gimme all items arrived since the last call” here.

On the other hand, polling the queue for single items could lead to a situation that producer and consumer are blocking each other for a short time and every time the consumer asks for a new item, another item is available due to the fact that the consumer has been blocked just long enough for the producer to create and put a new item. So you have to implement your own time limit to avoid blocking the UI thread too long in this case. Using drainTo once and release the event handling thread afterwards is much easier.

Holger
  • 285,553
  • 42
  • 434
  • 765