juc中ArrayBlockingQueue为什么出入用同一个锁?

昨天突然想到一个问题,为什么juc中ArrayBlockingQueue用一个锁(两个condition),而LinkedBlockingQueue用两个锁(两个condition)实现。

这导致了后者可以一边取一边放,而前者不行。

为了探究其设计的原因,产生了如下qa(自己和自己)


Q:为什么ArrayBlockingQueue put和take不能并行?

A:因为put 和 take用同一个reetrantlock实现。


Q:那改成两个reetranLock就可以并行take和put了吗?

A:不行。因为其中count是int而不是AtomicInteger。会因为和无法原子性修改以及编译器重排序导致其他问题。


Q:那修改int成AtomicInteger就可以了吗?

A:。。。大概吧。。。

   (实践尝试后。。)

    还是不行,因为这样通知的方式也要该,不能直接condition.signal()而要先获得另外一把锁再通知。


Q:那现在可以并行存取了吗?

A:可以了。


Q:那这样修改后效率有提高吗?

A:我试一下。。。(艾玛 太蛋疼了 周一去公司试好了 宿舍的破电脑 哎。。。)

    我先猜测,应该没有提高吧(douglea脑残粉- -哈哈哈)


Q:假设没有提高,你觉得原因是什么呢?
A:LinkedBlockingQueue的较大一部分时间需要构造节点,导致较长的等待。所以同时存取有较大优化。

    而ArrayBlockingQueue的不用构造节点,加锁和解锁的时间可能占比较大。

   转成双锁之后,对比原来的存取操作,需要多竞争两次。一次是Atomic变量的cas操作,另一次是获得另一把锁的通知操作。可能这部分的损耗,已经比并发存取带来收益更大。


Q:那你怎么证明你上述的观点是正确的呢

A:。。。周一去公司自己实现一个,然后测试一下。


好,周一再见- -。

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值