1. 程式人生 > >併發程式設計-concurrent指南-交換機Exchanger

併發程式設計-concurrent指南-交換機Exchanger

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