亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

交換者 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 的使用場景和基本用法。希望大家在學習過程中,多思考勤練習,早日掌握之。