如何部分从BlockingQueue的同步中解脱

凡是阻塞队列,皆有同步

有人的地方就有江湖,有竞争的地方就要同步.同步也许是通过AQS实现,也许是通过synchronized实现,也许是通过XXX实现,反正皆有同步,没有同步兜底的阻塞队列都是fake news(川普口气)

屠龙之术中的取巧之术

in my opinion,我觉得阻塞队列确实是非常有用的,我觉得其是屠龙之术,能解决基本上所有问题,但是在一些特殊的情况下,我们其实不用屠龙之术,我们可以取巧.当然基于AQS的同步其实已经帮我们取巧了一些,类似于轻量级锁的cas让我们如沐春风.但是当竞争确实存在,这些官方取巧之术似乎又没有那么多用处.

取巧之术,不仅仅是在同步的时候取巧,我们可以选择去除竞争

有人的地方就有江湖,有竞争的地方就要同步

既然同步无法避免,那么我们可以选择去除竞争.

如何去除竞争?

  • 假如你只有两个线程,那么我们的数据结构是一个链表,那么其实基于最简单的LinkedList你就可以实现头插入和尾插入,这个时候是不是就毫无竞争?大名鼎鼎的密取模式其实也有这种思想,LinekdBlockQueue的插入和取出其实也是用两个锁分离了读写的竞争.
  • 假如你有多个线程,怎么办?那么我们还是采取这种思想,
    • 要么给多个线程每个线程分配对应的list让其写入.最后通过list.addAll来归并或者通过ArrayBlockingQueue.addAll来归并(当然这个时候你merge的时候一定要将写入的容器的最大大小给初始化好,不然途中扩容多不好,更何况ArrayBlockingQueue必须指定大小2333)
    • 或者分配一个大数组,让每个线程去写入其对应分配数量的from index到end index的slot插槽.最后你Arrays.asList()转换一下,轻松拿下,也是毫无竞争.

去除竞争,就是采取隔离的方式,将竞争去除,当然也只在一些特殊的情况下使用,但是掌握这个取巧的思想是必要的。
之于分布式事务等复杂的模型,与其随波逐流使用分布式事务,然后在CA之间困难抉择,不如直接避免分布式事务.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章