前面三篇博客分別介紹了CyclicBarrier、CountDownLatch、Semaphore,如今介紹併發工具類中的最後一個Exchange。Exchange是最簡單的也是最複雜的,簡單在於API很是簡單,就一個構造方法和兩個exchange()方法,最複雜在於它的實現是最複雜的(本文不解釋。太複雜)算法
在API是這麼介紹的:能夠在對中對元素進行配對和交換的線程的同步點。每一個線程將條目上的某個方法呈現給 exchange 方法,與夥伴線程進行匹配,而且在返回時接收其夥伴的對象。Exchanger 可能被視爲 SynchronousQueue 的雙向形式。Exchanger 可能在應用程序(好比遺傳算法和管道設計)中頗有用。數據結構
Exchanger,它容許在併發任務之間交換數據。具體來講,Exchanger類容許在兩個線程之間定義同步點。當兩個線程都到達同步點時,他們交換數據結構,所以第一個線程的數據結構進入到第二個線程中,第二個線程的數據結構進入到第一個線程中。併發
public class ExchangerTest { private static final Exchanger<String> exgr = new Exchanger<String>(); private static ExecutorService threadPool = Executors.newFixedThreadPool(2); public static void main(String[] args) { threadPool.execute(new Runnable() { @Override public void run() { try { String A = "銀行流水A";// A錄入銀行流水數據 exgr.exchange(A); } catch (InterruptedException e) { } } }); threadPool.execute(new Runnable() { @Override public void run() { try { String B = "銀行流水B";// B錄入銀行流水數據 String A = exgr.exchange("B"); System.out.println("A和B數據是否一致:" + A.equals(B) + ",A錄入的是:" + A + ",B錄入是:" + B); } catch (InterruptedException e) { } } }); threadPool.shutdown(); } }
示例2ide
public class ExchangerTest { static class Producer implements Runnable{ //生產者、消費者交換的數據結構 private List<String> buffer; //步生產者和消費者的交換對象 private Exchanger<List<String>> exchanger; Producer(List<String> buffer,Exchanger<List<String>> exchanger){ this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { for(int i = 1 ; i < 5 ; i++){ System.out.println("生產者第" + i + "次提供"); for(int j = 1 ; j <= 3 ; j++){ System.out.println("生產者裝入" + i + "--" + j); buffer.add("buffer:" + i + "--" + j); } System.out.println("生產者裝滿,等待與消費者交換..."); try { exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } } } } static class Consumer implements Runnable { private List<String> buffer; private final Exchanger<List<String>> exchanger; public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) { this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { for (int i = 1; i < 5; i++) { //調用exchange()與消費者進行數據交換 try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("消費者第" + i + "次提取"); for (int j = 1; j <= 3 ; j++) { System.out.println("消費者 : " + buffer.get(0)); buffer.remove(0); } } } } public static void main(String[] args){ List<String> buffer1 = new ArrayList<String>(); List<String> buffer2 = new ArrayList<String>(); Exchanger<List<String>> exchanger = new Exchanger<List<String>>(); Thread producerThread = new Thread(new Producer(buffer1,exchanger)); Thread consumerThread = new Thread(new Consumer(buffer2,exchanger)); producerThread.start(); consumerThread.start(); } }
生產者第1次提供 生產者裝入1--1 生產者裝入1--2 生產者裝入1--3 生產者裝滿,等待與消費者交換... 生產者第2次提供 消費者第1次提取 生產者裝入2--1 消費者 : buffer:1--1 生產者裝入2--2 生產者裝入2--3 生產者裝滿,等待與消費者交換... 消費者 : buffer:1--2 消費者 : buffer:1--3 消費者第2次提取 消費者 : buffer:2--1 消費者 : buffer:2--2 消費者 : buffer:2--3 生產者第3次提供 生產者裝入3--1 生產者裝入3--2 生產者裝入3--3 生產者裝滿,等待與消費者交換... 生產者第4次提供 生產者裝入4--1 生產者裝入4--2 生產者裝入4--3 生產者裝滿,等待與消費者交換... 消費者第3次提取 消費者 : buffer:3--1 消費者 : buffer:3--2 消費者 : buffer:3--3 消費者第4次提取 消費者 : buffer:4--1 消費者 : buffer:4--2 消費者 : buffer:4--3