如何部分從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之間困難抉擇,不如直接避免分佈式事務.

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