1. 程式人生 > 其它 >面試突擊49:說一下 JUC 中的 Exchange 交換器?

面試突擊49:說一下 JUC 中的 Exchange 交換器?

Exchange(交換器)顧名思義,它是用來實現兩個執行緒間的資料交換的,它誕生於 JDK 1.5,它有兩個核心方法:

  • exchange(V x):等待另一個執行緒到達此交換點,然後將物件傳輸給另一個執行緒,並從另一個執行緒中得到交換的物件。如果另一個執行緒未到達此交換點,那麼此執行緒會一直休眠(除非遇了執行緒中斷)。
  • exchange(V x, long timeout, TimeUnit unit):等待另一個執行緒到達此交換點,然後將物件傳輸給另一個執行緒,並從另一個執行緒中得到交換的物件。如果另一個執行緒未到達此交換點,那麼此執行緒會一直休眠,直到遇了執行緒中斷,或等待的時間超過了設定的時間,那麼它會丟擲異常。

也就是說 exchange 方法就是一個交換點,執行緒會等待在此交換點,直到有另一個執行緒也呼叫了 exchange 方法(相當於進入到了此交換點),這時他們會互換資料,然後執行後續的程式碼。

基礎使用

Exchange 的基礎使用如下,我們建立兩個執行緒來模擬“一手交錢、一手交貨”的場景,執行緒 1 先準備好錢進入交換點,然後等待執行緒 2 在 2s 之後準備好貨(物),之後再彼此互動資料,執行後續的流程,具體實現程式碼如下:

import java.time.LocalDateTime;
import java.util.concurrent.Exchanger;

public class ExchangeExample {
    // 建立一個互動器
    private final static Exchanger<String> exchange = new Exchanger<>();
    public static void main(String[] args) {
        // 執行緒 1【準備錢】
        new Thread(() -> {
            System.out.println("執行緒1:準備籌錢中...| Time:" + LocalDateTime.now());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String moeny = "1000 萬";
            System.out.println("執行緒1:錢準備好了【1000 萬】。| Time:" + 
                               LocalDateTime.now());
            try {
                // 執行資料交換【交易】
                String result = exchange.exchange(moeny);
                System.out.println("執行緒1:交易完成,得到【" + result +
                        "】 | Time:" + LocalDateTime.now());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        // 執行緒 2【準備貨】
        new Thread(() -> {
            System.out.println("執行緒2:準備物品中【西伯利亞新鮮空氣】...| Time:" + 
                               LocalDateTime.now());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String goods = "西伯利亞新鮮空氣";
            System.out.println("執行緒2:物品準備好了【西伯利亞新鮮空氣】。| Time:" + 
                               LocalDateTime.now());
            try {
                // 執行資料交換【交易】
                String result = exchange.exchange(goods);
                System.out.println("執行緒2:交易完成,得到【" + result +
                        "】 | Time:" + LocalDateTime.now());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

以上程式的執行結果如下:

總結

Exchange 交換器是用來實現兩個執行緒間的資料交換的,Exchanger 可以互動任意資料型別的資料,只要在建立的時候定義泛型型別即可。它的核心方法為 exchange,當執行緒執行到此方法之後,會休眠等待另一個執行緒也進入交換點,如果另一個執行緒也進入了交換點(也執行到了 exchange 方法),此時二者會交換資料,並執行後續的流程。

是非審之於己,譭譽聽之於人,得失安之於數。

公眾號:Java面試真題解析

面試合集:https://gitee.com/mydb/interview