Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to prefer LinkedBlockingQueue over ArrayBlockingQueue?

When to prefer LinkedBlockingQueue over ArrayBlockingQueue?

Which data structure to use among LinkedBlockingQueue and ArrayBlockingQueue when:

  1. You want an efficient read and write
  2. should have lesser memory footprints

Although there is a similar question but it does not highlight the fact that which should be preferred?

Links:

  • Java: ArrayBlockingQueue vs. LinkedBlockingQueue
  • What is the Difference between ArrayBlockingQueue and LinkedBlockingQueue
like image 206
Vaibhav Gupta Avatar asked Mar 13 '16 07:03

Vaibhav Gupta


People also ask

When would you use a blocking queue?

BlockingQueue is a java Queue that support operations that wait for the queue to become non-empty when retrieving and removing an element, and wait for space to become available in the queue when adding an element.

Is ArrayBlockingQueue thread-safe?

ArrayBlockingQueue is thread-safe. The Iterator provided in iterator() method traverses the elements in order from first (head) to last (tail). It supports an optional fairness policy for ordering waiting producer and consumer threads.

What is LinkedBlockingQueue?

The LinkedBlockingQueue is an optionally-bounded blocking queue based on linked nodes. It means that the LinkedBlockingQueue can be bounded, if its capacity is given, else the LinkedBlockingQueue will be unbounded. The capacity can be given as a parameter to the constructor of LinkedBlockingQueue.


2 Answers

Boris the Spider has already outlined the most visible difference between ArrayBlockingQueue and LinkedBlockingQueue - the former is always bounded, while the latter can be unbounded.

So in case you need an unbounded blocking queue, LinkedBlockingQueue or a LinkedTransferQueue used as a BlockingQueue are your best bets from the java.util.concurrent toolbox.

But let's say you need a bounded blocking queue. In the end, you should choose an implementation based on extensive experimenting with a simulation of your real-world workload. Nevertheless, here are some notes that can help you with your choice or with interpreting the results from the experiment:

  • ArrayBlockingQueue can be created with a configurable (on/off) scheduling fairness policy. This is great if you need fairness or want to avoid producer/consumer starvation, but it will cost you in throughput.
  • ArrayBlockingQueue pre-allocates its backing array, so it doesn't allocate nodes during its usage, but it immediately takes what can be a considerable chunk of memory, which can be a problem if your memory is fragmented.
  • ArrayBlockingQueue should have less variability in performance, because it has less moving parts overall, it uses a simpler and less-sophisticated single-lock algorithm, it does not create nodes during usage, and its cache behavior should be fairly consistent.
  • LinkedBlockingQueue should have better throughput, because it uses separate locks for the head and the tail.
  • LinkedBlockingQueue does not pre-allocate nodes, which means that its memory footprint will roughly match its size, but it also means that it will incur some work for allocation and freeing of nodes.
  • LinkedBlockingQueue will probably have worse cache behavior, which may affect its own performance, but also the performance of other components due to false sharing.

Depending on your use-case and how much do you care about performance, you may also want to look outside of java.util.concurrent and consider Disruptor (an exceptionally fast, but somewhat specialized bounded non-blocking ring buffer) or JCTools (a variety of bounded or unbounded queues with different guarantees depending on the number of producers and consumers).

like image 131
Dimitar Dimitrov Avatar answered Sep 22 '22 17:09

Dimitar Dimitrov


From the JavaDoc for ArrayBlockingQueue

A bounded blocking queue backed by an array.

Emphasis mine

From the JavaDoc for LinkedBlockingQueue:

An optionally-bounded blocking queue based on linked nodes.

Emphasis mine

So if you need a bounded queue you can use either, if you need an unbounded queue you must use LinkedBlockingQueue.

For a bounded queue, then you would need to benchmark to work out which is better.

like image 36
Boris the Spider Avatar answered Sep 25 '22 17:09

Boris the Spider