ArrayBlockingQueue 的锁是读写不分离的。 而 LinkedBlockingQueue 的锁是读写分离的。这样就可以同时读和写了。 为什么要这么设计? 网上搜了一大圈答案都不太满意。
这里还有对 ArrayBlockingQueue 进行改造的。 https://blog.csdn.net/icepigeon314/article/details/93792519 貌似改造后效果还更好了, 为啥 Java 不一开始就这么设计?
1
HelloAmadeus 2019-09-17 15:30:39 +08:00 via iPhone
从数据结构上理解哈。数据 queue 有一个 index,读写都得改这个 index,列表 queue 读改表头,写改表尾,互不干扰。
|
2
guyeu 2019-09-17 15:58:58 +08:00
一楼说的对了一半,ArrayBlockingQueue 有两个 index,一个是 takeIndex 用于读,一个是 putIndex 用于写,从 index 的角度,可以做成读写分离,问题在于还有一个整数 count,记录队列里元素的数量,不管是读还是写都要修改这个整数的值,所以不管读还是写都要锁一下。
LinkedBlockingQueue 用 AtomicInteger 来记录元素数量,这个读写不分离的锁被隐藏在了 AtomicInteger 里,锁的粒度更细了。而 ArrayBlockingQueue 在读写元素时的运算量很小,所以没必要用太细粒度的锁。 |
3
monetto OP |