併發程式設計-concurrent指南-交換機Exchanger
阿新 • • 發佈:2018-12-20
java.util.concurrent包中的Exchanger類可用於兩個執行緒之間交換資訊。可簡單地將Exchanger物件理解為一個包含兩個格子的容器,通過exchanger方法可以向兩個格子中填充資訊。當兩個格子中的均被填充時,該物件會自動將兩個格子的資訊交換,然後返回給執行緒,從而實現兩個執行緒的資訊交換。
另外需要注意的是,Exchanger類僅可用作兩個執行緒的資訊交換,當超過兩個執行緒呼叫同一個exchanger物件時,得到的結果是隨機的,exchanger物件僅關心其包含的兩個“格子”是否已被填充資料,當兩個格子都填充資料完成時,該物件就認為執行緒之間已經配對成功,然後開始執行資料交換操作。
Exchanger可以在兩個執行緒之間交換資料,只能是2個執行緒,他不支援更多的執行緒之間互換資料。
Exchanger是在兩個任務之間交換物件的柵欄,當這些任務進入柵欄時,它們各自擁有一個物件。當他們離開時,它們都擁有之前由物件持有的物件。
它典型的應用場景是:一個任務在建立物件,這些物件的生產代價很高昂,而另一個任務在消費這些物件。通過這種方式,可以有更多的物件在被建立的同時被消費。
public class ExchangerRunnable implements Runnable{ private Exchanger<String> exchanger;private String data; private int random; public ExchangerRunnable(Exchanger exchanger,String data,int random){ this.exchanger = exchanger; this.data = data; this.random = random; } @Override public void run() { System.out.println(Thread.currentThread().getName()+",資料:"+data); try { TimeUnit.SECONDS.sleep(random); String data_new = exchanger.exchange(data); System.out.println(Thread.currentThread().getName()+",資料:"+data_new); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Main { public static void main(String[] args) { //交換機 Exchanger exchanger = new Exchanger(); ExchangerRunnable exchangerRunnable = new ExchangerRunnable(exchanger,"aa",3); ExchangerRunnable exchangerRunnable1 = new ExchangerRunnable(exchanger,"bb",10); new Thread(exchangerRunnable).start(); new Thread(exchangerRunnable1).start(); } }
結果:
Thread-0,資料:aa Thread-1,資料:bb Thread-0,資料:bb Thread-1,資料:aa
注意:
1.當執行緒A呼叫Exchange物件的exchange()方法後,他會陷入阻塞狀態,直到執行緒B也呼叫了exchange()方法,然後以執行緒安全的方式交換資料,之後執行緒A和B繼續執行。
2.多個執行緒時,有且只有兩個執行緒進入資料交換。
原始碼地址:https://github.com/qjm201000/concurrent_exchanger.git