天天看點

阿裡P8終于講明白了生産者-消費者模式!

核心是一個任務隊列,生産者線程生産任務,并将任務添加到任務隊列中,而消費者線程從任務隊列中擷取任務并執行。該模式有如下優點:

解耦

解耦的一個關鍵就是元件之間的依賴關系和通信方式必須受限。在生産者-消費者模式中,生産者和消費者沒有任何依賴關系,它們彼此之間的通信隻能通過任務隊列,是以生産者-消費者模式是一個不錯的解耦方案。

異步

平衡生産者和消費者的速度差異。生産者線程隻需要将任務添加到任務隊列,無需等待任務被消費者線程執行完,即任務的生産和消費是異步的。

異步化處理最簡單的方式就是建立一個新的線程去處理,那中間加個“任務隊列”究竟有什麼用呢?主要還是用于平衡生産者和消費者的速度差異。

假設生産者速率慢,消費者速率高,1:3,若生産者有3個線程

  • 采用建立新線程,則會建立3個子線程
  • 采用生産者-消費者模式,消費線程隻需要1個

由于Java線程和os線程一一對應,線程建立得太多,會增加上下文切換成本。生産者-消費者模式恰好能支援使用合适數量的線程。

批量執行

若使用輕量級線程,就沒有必要平衡生産者和消費者速度差異,那是否說明生産者-消費者模式在性能優化方面就無用武之地?

不是,有一類并發場景應用生産者-消費者模式就有奇效:批量執行任務。

  • 用1000個線程并發執行,每個線程INSERT一條資料
  • 用1個線程,執行一個批量SQL,一次性把1000條資料INSERT進去

    該方案效率更高,這就是批量執行場景。