面試突擊49:說一下 JUC 中的 Exchange 交換器?
阿新 • • 發佈:2022-05-18
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面試真題解析