在Java中本地進行執行緒間資料傳輸的三種方式和原始碼展示

banq發表於2019-02-20

線上程之間進行通訊或發訊號時首先想到的是java.lang.Object類方法:wait,notify和notifyAll。這是最基本和最廣泛認可的概念,但本部落格並非講這些。
JVM例項上執行的執行緒缺少強大的預設模型,就像在UNIX中進行互動通訊一樣,儘管有一些第三方框架可以幫助我們實現這一意圖並在角落案例中執行良好,本部落格特別針對使用Java中的三個本地概念進行執行緒間通訊: Cyclic Barrier迴圈屏障,Count Down Latch倒數計時鎖存和Pipes管道。

1.Cyclic Barrier
擴充套件java.util.concurrent.CyclicBarrier類以進行執行緒間資料傳輸。它基本上是一種同步技術,它允許每個執行緒的程式計數器在各個執行緒中的公共屏障點上停止,此時,可以使用共享狀態傳輸資料,然後執行緒可以相應地繼續。
演示的示例程式碼將使用生產者 - 消費者模型。父執行緒啟用class.Producer和class.Consumer執行緒啟動。當生產者從檔案中讀取資料時,消費者首先到達公共屏障並停止。生產者執行緒將結果儲存在父執行緒的阻塞佇列中。一旦生產者到達屏障點,此時生產者和消費者都會釋放屏障,消費者從佇列中檢索資料並繼續。
這個模型的一個好的用例是執行緒的輸入依賴於另一個執行緒的輸出。在這種情況下,消費者執行緒可以執行所有必要的啟動並在屏障處等待接收輸入資料。按照此github連結進行迴圈屏障的完整實施。

邏輯模板:
class.Producer thread 
step1:start 
step2:進行必要的計算和邏輯
step3:將要傳輸的所有資料寫入阻塞佇列
step4:達到迴圈屏障點,如果所有的執行緒都到達屏障點 - >繼續
步驟5:進行清理和/或結束

class.Consumer thread 
step1:start 
step2:啟動任何與生產者無關的資料邏輯處理
step3 到達迴圈屏障點,如果所有執行緒到達障礙 - >繼續
step4:從佇列中刪除資料
step5:處理資料,清理並結束


2.Count Down Latch
這是一種在等待和到達模型中使用的同步技術,但它在這裡以生產者 - 消費者方式實現。
生產者執行緒到達某一點,打上一個標誌並立即繼續前進,而不像迴圈屏障那樣的生產者執行緒會暫停在這裡,消費者執行緒在某個點停止開始程式計數器計數,一直等待生產者執行緒打上一個標誌以後才繼續執行。
這個模型可以被修改後可用於執行緒間通訊。生產者執行緒在到達該點之前將一些資料推送到阻塞佇列然後引發一個標誌,等待的消費者跟蹤所有這些標誌並等待獲得所需的標誌號碼,然後它開始從阻塞佇列中提取資料。
演示的示例程式碼將具有兩個生成器執行緒,一個消費者者執行緒和一個大小為2的有界阻塞佇列。生產者執行緒每個讀取不同的輸入檔案,然後將其傳輸到生產者執行緒,生產者執行緒將其列印到螢幕上。好用例是當伺服器中的資料庫物件僅批次寫入時,它充當使用者並等待預設號碼。許多生產者執行緒將其資料推入佇列,引發標誌並繼續而不等待。按照這個github連結進行倒數計時鎖存器的完整實現。

邏輯模板:
class.Producer1和class.Producer2
step1:啟動 
step2:做必要的計算和邏輯
step3:寫入要傳輸的所有資料到阻塞佇列
step4:打上標誌並繼續而不等待
step5:做一些邏輯並結束

class.Consumer 
step1:啟動
step2:做一些邏輯並等待一個點接收資料
step3:跟蹤標誌/鎖存器,如果數量到達 - >繼續
step4:從佇列中拉出資料step5 
:使用資料並結束


3.來自java.io的Pipes
 class.PipedReader 和class.PipedWriter 允許在定義的點與其他執行緒直接通訊。生產者和消費者必須共同訪問某一點,生產開始以塊的形式推送資料,正在等待管道開啟的消費者者開始提取資料。
理解和實施這個概念相對簡單。pipe在現場環境中表現不佳,因此在開發人員社群中已被棄用。另一個主要缺點是它僅支援一對一轉移。只能有一個生產者和一個消費者。一個很好的用例是當它用於在一次性任務中引導資料時,它與較新的java.nio包一起使用。關注pipeReader和pipeWriter完整實現的github連結。

邏輯模板
class.Producer thread 
step1:啟動
step2:做一些邏輯併到達執行管道的迴圈
step3:將資料推入流中並在完成後繼續
step4:做一些邏輯並結束

class.Consumer thread 
step1:啟動
step2:做一些邏輯併到達管道讀取器點
step3:一旦管道有值拉資料並儲存它
step5:完全讀取所有資料,做一些邏輯並結束


異構執行緒之間的執行緒間通訊的三種方式只是作者在完成工作時修改/擴充套件本機概念的努力。如在用例場景中所理解的,倒數計時鎖存器具有更廣泛的可用性範圍並且可以被廣泛採用。

一個主要提示是異常,提供障礙或鎖存器具有底層異常,異常處理程式也有機會重試資料傳輸。這些概念的實現很廣泛,本部落格試圖將生產者 - 消費者的註釋和github示例放入其中。

相關文章