ArrayBlockingQueue uses a single lock for insertion and removal but LinkedBlockingQueue uses 2 separate locks

被刻印的时光 ゝ 提交于 2019-11-27 01:58:03

问题


I was going through the source code of ArrayBlockingQueue and LinkedBlockingQueue. LinkedBlockingQueue has a putLock and a takeLock for insertion and removal respectively but ArrayBlockingQueue uses only 1 lock. I believe LinkedBlockingQueue was implemented based on the design described in Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms. In this paper, they mention that they keep a dummy node so that enqueuers never have to access head and dequeuers never have to access tail which avoids deadlock scenarios. I was wondering why ArrayBlockingQueue doesn't borrow the same idea and use 2 locks instead.


回答1:


ArrayBlockingQueue has to avoid overwriting entries so that it needs to know where the start and the end is. A LinkedBlockQueue doesn't need to know this as it lets the GC worry about cleaning up Nodes in the queue.




回答2:


I was wondering why ArrayBlockingQueue doesn't borrow the same idea and use 2 locks instead.

Because the ArrayBlockingQueue uses a much simpler data structure to hold the queue items.

The ArrayBlockingQueue stores its data in one private final E[] items; array. For multiple threads to deal with this same storage space, either if adding or dequeuing, they have to use the same lock. This is not only because of memory barrier but because of mutex protection since they are modifying the same array.

LinkedBlockingQueue on the other hand is a linked list of queue elements that is completely different and allows for the ability to have a dual lock. It is the internal storage of the elements in the queue that enabled the different lock configurations.




回答3:


2 locks are used in LBQ to restrict access to head and lock concurrently. The head lock disallows two elements from being removed concurrently and tail lock disallows two elements from being concurrently added to the queue. the two lock together prevent races.




回答4:


I think its possible for ABQ to borrow the same idea as LBQ. Please refer to my code http://pastebin.com/ZD1uFy7S and a similar question i asked on SO ArrayBlockingQueue: concurrent put and take.

The reason why they didn't used it, is mainly because of the complexity in implementation especially iterators and trade off between complexity and performance gain was not that lucrative.

For more reference please have a look at http://jsr166-concurrency.10961.n7.nabble.com/ArrayBlockingQueue-concurrent-put-and-take-tc1306.html .



来源:https://stackoverflow.com/questions/11015571/arrayblockingqueue-uses-a-single-lock-for-insertion-and-removal-but-linkedblocki

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