Synchronization in BlockingQueue is implemented by Locks while ConcurrentLinkedQueue uses Lock-free algorithm that involves CAS. But my question is regarding context switch overhead. if there are 10 threads de-queuing requests from BlockingQueue then only one at a time will Lock the queue and 9 context switches will be placed(9 threads will loose), while in case of ConcurrentLinkedQueue there is no context switch overhead but as far as time slicing is concerned all 10 threads will be context switched again and again after there time slice ending and will this not cause more context switch overhead as compared to BlockingQueue? Which one results in less context switch overhead?
Asked
Active
Viewed 433 times
4
-
If two threads call `arrayBlockingQueue.poll()`, there probably won't be any context switch. First because, unless the threads are doing nothing but poll the queue as fast as possible and throwing the nodes away, they probably will spend a relatively small fraction of time inside the mutex, and there won't be much contention for it. Second because, even when they do occasionally collide, your JVM probably uses a sophisticated hybrid locking algorithm that won't block the losing thread until the winner has spent more than some trivial amount of time holding the mutex. – Solomon Slow Nov 19 '15 at 20:57
-
But you're right, if two or more threads call `concurrentLinkedQueue.poll()` as fast as possible, then that won't block any of them, ever. – Solomon Slow Nov 19 '15 at 21:02
-
1my opinion is that if you reach a situation where you have 10 threads waiting for an access to a resource concurrently, then your issue is not how to handle that contention, but rather why you have so many threads there in the first place. CAS is not a panacea, it's an optimization, which only holds as long as you're not overflowing it. – didierc Nov 19 '15 at 21:21
1 Answers
0
ConcurrentLinkedQueue doesn't have a take(), so we cannot compare that. So you are comparing the .poll(). We can debate why you are not using BQ.take() and the fact that BQ.put() perform a signal() not a signalAll() and wakes only one thread, not 10, but that's another issue.
The BQ lock is implemented with Reentrant locks, themselves using CAS.
The only diff would be in the 'fairness' (see property of the reentrantlock) of such locking, and possibly the tighter lock coding (less depth of stackframes) of the concurrentlinkedqueue.
Microbenchmark that, check the CTX switch count in the OS, and the JVM profiler hotspots...

user2023577
- 1,752
- 1
- 12
- 23