Java API提供了一個同步輔助類Exchanger。它容許你在線程執行過程當中在線程之間交換數據。它的機制是在線程中設置通步點,當兩個線程都到達同步點之時,它們交換數據結構,所以第一個線程的數據結構進入到第二個線程中,同時第二個線程的數據結構進入到第一個線程中。java
Exchange應用侷限於兩個線程,因此咱們能夠使用Exchange來模擬只有一個生產者和一個消費者的生產者-消費者問題。緩存
建立一個生產者線程類Producer,聲明一個List<String>做爲緩衝區,一個Exchange<List<String>>用來和消費者交換數據。線程的執行方法中,循環10次,每次向緩衝區中加入10個記錄並調用Exchange.exchange(),方法來和消費者交換數據。最後打印緩衝區記錄數和當前循環次數。數據結構
public class Producer implements Runnable { private List<String> buffer; private Exchanger<List<String>> exchanger; public Producer(List<String> buffer, Exchanger<List<String>> exchanger) { this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { int cycle = 1; for (int i = 0; i < 10; i++) { System.out.printf("Producer: Cycle %d\n", cycle); for (int j = 0; j < 10; j++) { String message = "Event" + (i * 10 + j); System.out.printf("Producer: %s\n", message); buffer.add(message); } try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Producer: %d\n", buffer.size()); cycle++; } } }
建立一個消費者線程類,一樣聲明一個數據緩衝區List<String>和一個Exchange用於和生產者交換數據。執行10次循環,每次循環使用exchanger.exchange()方法等待和生產者交換數據,交換數據成功後打印數據緩衝區的內容。ide
public class Consumer implements Runnable{ private List<String> buffer; private Exchanger<List<String>> exchanger; public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) { this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { int cycle = 1; for (int i = 0; i < 10; i++) { System.out.printf("Consumer: Cycle %d\n", cycle); try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Consumer: Buffer size %d\n", buffer.size()); for(Iterator<String> iterator = buffer.iterator(); iterator.hasNext();) { String message = iterator.next(); System.out.printf("Consumer: %s\n", message); iterator.remove(); } cycle++; } } }
建立主方法類,聲明兩個List<Stting>分別做爲生產者和消費者的數據緩衝區,聲明一個Exchanger對象用於在生產者線程和消費者線程之間交換數據。而後啓動兩個線程。this
public class Main { 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 threadP = new Thread(new Producer(buffer1, exchanger)); Thread threadC = new Thread(new Consumer(buffer2, exchanger)); threadP.start(); threadC.start(); } }
查看控制檯執行結果。執行開始後消費者線程持有一個空緩衝區,並等待和生產者線程在第一個同步點交換數據。生產者則向一個空的緩衝區中寫入10條記錄,而後再第一個同步點與消費者交換數據。在這個同步點上,消費者得到生產者的10條記錄的緩存,生產者得到消費者的空緩存,因此你會看到消費者打印緩存中的10條記錄,而生產者交換後的緩存數據量爲0.線程
Producer: Cycle 1 Producer: Event0 Producer: Event1 Producer: Event2 Producer: Event3 Producer: Event4 Producer: Event5 Producer: Event6 Producer: Event7 Producer: Event8 Producer: Event9 Consumer: Cycle 1 Producer: 0 Producer: Cycle 2 Producer: Event10 Producer: Event11 Producer: Event12 Producer: Event13 Producer: Event14 Producer: Event15 Producer: Event16 Producer: Event17 Producer: Event18 Producer: Event19 Consumer: Buffer size 10 Consumer: Event0 Consumer: Event1 Consumer: Event2 Consumer: Event3 Consumer: Event4 Consumer: Event5 Consumer: Event6 Consumer: Event7 Consumer: Event8 Consumer: Event9 Consumer: Cycle 2 Consumer: Buffer size 10 Consumer: Event10 Consumer: Event11 Consumer: Event12 Consumer: Event13 Consumer: Event14 Consumer: Event15 Consumer: Event16 Consumer: Event17 Consumer: Event18 Consumer: Event19 Consumer: Cycle 3 Producer: 0 Producer: Cycle 3 Producer: Event20 Producer: Event21 Producer: Event22 Producer: Event23 Producer: Event24 Producer: Event25 Producer: Event26 Producer: Event27 Producer: Event28 Producer: Event29 Producer: 0 Producer: Cycle 4 Producer: Event30 Producer: Event31 Consumer: Buffer size 10 Consumer: Event20 Producer: Event32 Consumer: Event21 Consumer: Event22 Consumer: Event23 Producer: Event33 Consumer: Event24 Consumer: Event25 Consumer: Event26 Consumer: Event27 Consumer: Event28 Consumer: Event29 Consumer: Cycle 4 Producer: Event34 Producer: Event35 Producer: Event36 Producer: Event37 Producer: Event38 Producer: Event39 Producer: 0 Producer: Cycle 5 Producer: Event40 Consumer: Buffer size 10 Consumer: Event30 Consumer: Event31 Consumer: Event32 Consumer: Event33 Producer: Event41 Producer: Event42 Consumer: Event34 Producer: Event43 Consumer: Event35 Producer: Event44 Consumer: Event36 Producer: Event45 Consumer: Event37 Consumer: Event38 Consumer: Event39 Consumer: Cycle 5 Producer: Event46 Producer: Event47 Producer: Event48 Producer: Event49 Producer: 0 Producer: Cycle 6 Consumer: Buffer size 10 Consumer: Event40 Consumer: Event41 Producer: Event50 Consumer: Event42 Consumer: Event43 Consumer: Event44 Producer: Event51 Consumer: Event45 Producer: Event52 Consumer: Event46 Producer: Event53 Consumer: Event47 Producer: Event54 Producer: Event55 Producer: Event56 Producer: Event57 Producer: Event58 Producer: Event59 Consumer: Event48 Consumer: Event49 Consumer: Cycle 6 Consumer: Buffer size 10 Consumer: Event50 Consumer: Event51 Consumer: Event52 Consumer: Event53 Consumer: Event54 Consumer: Event55 Consumer: Event56 Consumer: Event57 Consumer: Event58 Consumer: Event59 Consumer: Cycle 7 Producer: 0 Producer: Cycle 7 Producer: Event60 Producer: Event61 Producer: Event62 Producer: Event63 Producer: Event64 Producer: Event65 Producer: Event66 Producer: Event67 Producer: Event68 Producer: Event69 Producer: 0 Producer: Cycle 8 Producer: Event70 Producer: Event71 Producer: Event72 Producer: Event73 Producer: Event74 Producer: Event75 Producer: Event76 Producer: Event77 Producer: Event78 Producer: Event79 Consumer: Buffer size 10 Consumer: Event60 Consumer: Event61 Consumer: Event62 Consumer: Event63 Consumer: Event64 Consumer: Event65 Consumer: Event66 Consumer: Event67 Consumer: Event68 Consumer: Event69 Consumer: Cycle 8 Consumer: Buffer size 10 Producer: 0 Producer: Cycle 9 Consumer: Event70 Producer: Event80 Consumer: Event71 Consumer: Event72 Producer: Event81 Consumer: Event73 Producer: Event82 Consumer: Event74 Consumer: Event75 Consumer: Event76 Producer: Event83 Consumer: Event77 Producer: Event84 Producer: Event85 Consumer: Event78 Consumer: Event79 Consumer: Cycle 9 Producer: Event86 Producer: Event87 Producer: Event88 Producer: Event89 Producer: 0 Producer: Cycle 10 Consumer: Buffer size 10 Consumer: Event80 Producer: Event90 Producer: Event91 Consumer: Event81 Producer: Event92 Consumer: Event82 Producer: Event93 Consumer: Event83 Producer: Event94 Consumer: Event84 Consumer: Event85 Consumer: Event86 Consumer: Event87 Consumer: Event88 Producer: Event95 Producer: Event96 Producer: Event97 Producer: Event98 Consumer: Event89 Consumer: Cycle 10 Producer: Event99 Producer: 0 Consumer: Buffer size 10 Consumer: Event90 Consumer: Event91 Consumer: Event92 Consumer: Event93 Consumer: Event94 Consumer: Event95 Consumer: Event96 Consumer: Event97 Consumer: Event98 Consumer: Event99