I’m reading this:
In which Doug Lea says:
Usually, when you are putting something into a queue, you will have just allocated that new something. And similarly, when you take something out you usually use it and then let it become garbage. In which case the extra allocation for a queue node is not going to make much difference in overall GC, so you might as well go for the better scalability of LinkedBlockingQueue. I think this is the most common use case.
But, if you aren’t allocating the things put into queues, and don’t expect lots of threads to be contending when the queue is neither empty nor full, then ArrayBlockingQueue is likely to work better.
I want to know what does Aren't allocating the things put into queues mean?
Also, this sentence: don't expect lots of threads to be contending when the queue is neither empty nor full, then ArrayBlockingQueue is likely to work better, can someone explain that a little bit more specifically?
Advertisement
Answer
To me that seems to mean following:
-
I want to know what does
Aren't allocating the things put into queuesmean?This is about the GC overhead which they discus.
LinkedBlockingQueuecreates new internalNodeobject for every added item, which means it generates garbage and, as a result, causes garbage collection (GC).
Doug says that often the items we store in a queue are objects which:- are created right before they are added to the queue
- become unused (and eligible for GC) shortly after they are removed from the queue
In these cases the items themselves cause GC anyway, therefore it’s not a problem that
Nodeobjects require GC as well.But if you only store long-lived objects in a queue, then
LinkedBlockingQueuemight become the only thing that causes GC.
Then you might want to useArrayBlockingQueueinstead to avoid GC.
(ArrayBlockingQueuedoesn’t create any objects when items added/removed) -
Also, this sentence:
don't expect lots of threads to be contending when the queue is neither empty nor full, then ArrayBlockingQueue is likely to work better, can someone explain that a little bit more specifically?LinkedBlockingQueueuses two locks: one forput()and one fortake().
ArrayBlockingQueueuses one lock for bothput()andtake().
As a result when “the queue is neither empty nor full” (i.e. when neitherput()nortake()have to wait) and there are two threads: one executesput(), another one executestake()- if the queue is
LinkedBlockingQueue, then the threads don’t block each other - if the queue is
ArrayBlockingQueue, then one thread will have to wait until the other one is done
- if the queue is