首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Exchanger 實戰:雙線程數據緩衝區零拷貝交換模式

     編輯:Java 相關知識

Exchanger 是 JDK 併發包中獨特的同步點,支援兩個線程在同步點交換數據對象。本文通過「讀線程填充緩衝區、寫線程消費緩衝區」的雙緩衝模式演示其核心價值。

一、 核心場景:雙緩衝區生產消費

public class BufferExchanger {
    private static final Exchanger<List<String>> exchanger = new Exchanger<>();
    private static final int BUFFER_SIZE = 10;

    public static void main(String[] args) {
        new Thread(() -> { // 讀線程:生產數據
            List<String> buffer = new ArrayList<>();
            while (true) {
                buffer.clear();
                for (int i = 0; i < BUFFER_SIZE; i++) buffer.add("data-" + System.nanoTime());
                try { buffer = exchanger.exchange(buffer); } // 交換滿緩衝區,拿回空緩衝區
                catch (InterruptedException e) { break; }
            }
        }, "Reader").start();

        new Thread(() -> { // 寫線程:消費數據
            List<String> buffer = new ArrayList<>();
            while (true) {
                try { buffer = exchanger.exchange(buffer); } // 交換空緩衝區,拿回滿緩衝區
                catch (InterruptedException e) { break; }
                buffer.forEach(System.out::println); // 處理數據
                buffer.clear(); // 準備下輪
            }
        }, "Writer").start();
    }
}

二、 關鍵特性

  • 雙向同步:雙方同時到達 exchange 才能繼續,天然形成背壓。
  • 零拷貝交換:僅交換引用,無數據拷貝開銷,適合大對象緩衝區。
  • 泛型安全:Exchanger<V> 編譯期保證類型一致。

三、 適用場景 vs 不適用場景

適用不適用
雙線程管道流(讀/寫、壓縮/解壓、加密/解密)多生產者/多消費者(用 BlockingQueue)
雙緩衝區渲染(遊戲/圖形)單向數據流(用 BlockingQueue/Disruptor)
檢查點同步(雙線程協作算法)需廣播/多播的場景

四、 避坑指南

  • 交換對象必須可變且可復用(如 ArrayList.clear() 復用),否則無意義。
  • 若一方異常退出,另一方會永久阻塞在 exchange,需加超時機制(JDK 無直接支援,可用 Future.get(timeout) 包裝)。
  • 不要在 exchange 內做耗時操作,會阻塞對方線程。

五、 總結

Exchanger 是「雙線程零拷貝交換」的專用工具,用對場景極其優雅,濫用則增加複雜度。記住:只有兩個線程、雙向交換、可復用緩衝區 時才考慮它。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved