交換者 Exchanger
1. 前言
本節帶領大家認識第五個常用的 Java 并發工具類之 Exchanger。
本節先介紹 Exchanger 工具類表達的概念和最基本用法,接著通過一個生活中的例子為大家解釋 Exchanger 工具類的使用場合,然后通過簡單的編碼實現此場景,最后帶領大家熟悉 Exchanger 工具類的其他重要方法。
下面我們正式開始介紹吧。
2. 概念解釋
Exchanger 表示 “交換者”,此工具類提供了兩個線程在某個時間點彼此交換信息的功能。使用 Exchanger 的重點是成對的線程使用 exchange () 方法,當一對線程都到達了同步點時,彼此會進行信息交換。我們通過一張圖可直觀了解其邏輯。
概念已經了解了,Exchanger 工具類最基本的用法是怎樣的呢?看下面。
3. 基本用法
// 創建一個 Exchanger 對象
Exchanger exchanger = new Exchanger();
// 線程1開始處理邏輯
...
// 線程1將自己的信息交換給線程2,并一直等待線程2的交換動作
exchanger.exchange("待交換信息");
// 線程1等到了線程2的交換結果后繼續處理后繼邏輯
...
// 線程2開始處理邏輯
...
// 線程2將自己的信息交換給線程2,并一直等待線程1的交換動作
exchanger.exchange("待交換信息");
// 線程2等到了線程1的交換結果后繼續處理后繼邏輯
...
是不是很簡單,那 Exchanger 應用在哪些場合比較合適呢?下面我們給出最常用的場景說明。
4. 常用場景
Exchanger 工具類提供了成對的線程彼此同步數據的場合。我們舉一個生活中的例子說明:快遞員為客戶派送物品,客戶要求訂單采用貨到付款的方式進行支付。當快遞員送貨上門后,出示收款二維碼(或者 POM 刷卡支付),客戶當面掃碼(或刷卡)支付。在這個例子中,快遞員交換出去的是貨物收到的是款項,而客戶正好相反。我們用 Exchanger 工具類簡單實現這個場景,請看下面代碼。
5. 場景案例
import java.util.Random;
import java.util.concurrent.Exchanger;
public class ExchangerTest {
// 創建一個 Exchanger 對象
private static Exchanger<Object> exchanger = new Exchanger();
public static void main(String[] args) throws InterruptedException {
// 模擬快遞員
new Thread(() -> {
System.out.println( Thread.currentThread().getName() + "送貨上門中...");
// 模擬快遞送貨用時
try {
Thread.sleep(new Random().nextInt(10000));
} catch (Exception e) {}
System.out.println( Thread.currentThread().getName() + "貨物已經送到,等待客戶付款");
// 進行貨款交換
try {
Object money = exchanger.exchange("快遞件");
// 收到貨款
System.out.println("已經收到貨款" + money + ",繼續下一單派送...");
} catch (Exception e) {}
}, "快遞員").start();
// 模擬客戶
new Thread(() -> {
System.out.println( Thread.currentThread().getName() + "工作中...");
// 模擬工作中用時
try {
Thread.sleep(new Random().nextInt(10000));
} catch (Exception e) {}
System.out.println( Thread.currentThread().getName() + "接到快遞員取件電話,貨物已經送到");
try {
// 進行貨款交換
Object packagz = exchanger.exchange("1000元");
// 收到貨款
System.out.println("已經收到貨物" + packagz + "...");
} catch (Exception e) {}
}, "客戶").start();
}
}
運行上面代碼,我們觀察一下運行結果。
快遞員送貨上門中...
客戶工作中...
快遞員貨物已經送到,等待客戶付款
客戶接到快遞員取件電話,貨物已經送到
已經收到貨物快遞件...
已經收到貨款1000元,繼續下一單派送...
觀察結果,和我們的預期一致。
6. 其他方法介紹
Exchanger 工具類的用法比較簡單,其提供了兩個 exchange 方法,除過上面代碼中使用的方法之外,其還對進行了重載。
exchange (V, timeout, TimeUnit) 方法。
允許設置交換等待的超時時間,當時間過后還未交換到需要的對方數據,則不再等待,繼續后繼邏輯執行。
7. 小結
本節通過一個簡單的例子,介紹了 Exchanger 的使用場景和基本用法。希望大家在學習過程中,多思考勤練習,早日掌握之。