在兩個線程之間定義同步點,當兩個線程都到達同步點時,他們交換數據結構,所以第一個線程的數據結構進入到第二個線程中,第二個線程的數據結構進入到第一個線程中數據結構
在生產者-消費者情境模式中它包含了一個數緩衝區,一個或者多個生產者,一個或者多個消費中ide
下面是生產者和消費者的示例:this
/** * 生產者和消費者交換數據 */ public class MyExchanger { public static void main(String[] args) { Exchanger<List<String>> exchanger = new Exchanger<List<String>>(); Producer1 producer = new Producer1(new ArrayList<String>(), exchanger); Consumer1 consumer = new Consumer1(new ArrayList<String>(), exchanger); new Thread(producer).start(); new Thread(consumer).start(); } } /** 生產者線程*/ class Producer1 implements Runnable{ /** * 存儲交換的數據 */ private List<String> buffer; /** * 和消費者要交換的對象 */ private final Exchanger<List<String>> exchanger; Producer1(List<String> buffer,Exchanger<List<String>> exchanger){ this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { for(int i = 0 ; i < 2 ; i++){ String message = "" + i ; System.out.println("Produce的數據 : " + message); buffer.add(message); //調用exchange()與消費者進行數據交換 try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Produce收到來自Consumer的數據的長度 : " + buffer.size()); } } /** 消費者線程*/ class Consumer1 implements Runnable{ private List<String> buffer; private final Exchanger<List<String>> exchanger; public Consumer1(List<String> buffer,Exchanger<List<String>> exchanger){ this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { for(int i = 0 ; i < 2 ; i++){ //調用exchange()與消費者進行數據交換 try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } for(int j = 0 ; j < buffer.size() ; j++){ System.out.println("Consumer收到來自Produce的數據 : " + buffer.get(0)); buffer.remove(0); } } System.out.println("Consumer清空數據"); } }
控制檯輸出:spa
Produce的數據 : 0 Consumer收到來自Produce的數據 : 0 Produce的數據 : 1 Produce收到來自Consumer的數據的長度 : 0 Consumer收到來自Produce的數據 : 1 Consumer清空數據
在Exchanger中,若是一個線程已經到達了exchanger節點時,對於它的夥伴節點的狀況有三種:線程
一、若是它的夥伴節點在該線程到達之間已經調用了exchanger方法,則它會喚醒它的夥伴而後進行數據交換,獲得各自數據返回。code
二、若是它的夥伴節點尚未到達交換點,則該線程將會被掛起,等待它的夥伴節點到達被喚醒,完成數據交換。對象
三、若是當前線程被中斷了則拋出異常,或者等待超時了,則拋出超時異常blog