目录
Exchanger
案例说明
一、主程序
二、生产者
三、消费者
四、执行结果
Exchanger
Exchanger是JAVA并发API提供的两个并发任务间进行数据交换的工具类。Exchanger允许两个线程间定义一个同步点,当两个任务到达同步点时,他们能够交换内部的数据结构,将第一个线程的数据结构传递给第二个线程,反之亦然。
案例说明
案例模拟只有一个生产者和一个消费者的生产者-消费者问题。
一、主程序
模拟1对1的生产者和消费者问题
package xyz.jangle.thread.test.n3_7.exchanger;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Exchanger;/*** 3.7 Exchanger 两个并发任务间的数据交换* 模拟1对1的生产者和消费者问题* * @author jangle* @email jangle@jangle.xyz* @time 2020年8月13日 下午7:46:31* */
public class M {public static void main(String[] args) {List<String> buffer1 = new ArrayList<>();List<String> buffer2 = new ArrayList<>();Exchanger<List<String>> exchanger = new Exchanger<List<String>>();Producer producer = new Producer(buffer1, exchanger);Consumer consumer = new Consumer(buffer2, exchanger);new Thread(producer).start();new Thread(consumer).start();}}
二、生产者
先生产,再同步交换。
package xyz.jangle.thread.test.n3_7.exchanger;import java.util.List;
import java.util.concurrent.Exchanger;/*** 生产者对象 先生产,再同步交换* * @author jangle* @email jangle@jangle.xyz* @time 2020年8月13日 下午7:48:06* */
public class Producer implements Runnable {private List<String> buffer;private final Exchanger<List<String>> exchanger;public Producer(List<String> buffer, Exchanger<List<String>> exchanger) {super();this.buffer = buffer;this.exchanger = exchanger;}@Overridepublic void run() {for (int i = 1; i < 10; i++) {System.out.println("生产者第" + i + "期");for (int j = 0; j < 10; j++) {String msg = "" + (i * 10 + j);System.out.println("生产:"+msg);buffer.add(msg);}try {buffer = exchanger.exchange(buffer);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("生产者:交换后的缓冲区列表大小:" + buffer.size() + "对象:" + buffer);}}}
三、消费者
先同步交换,再消费。
package xyz.jangle.thread.test.n3_7.exchanger;import java.util.List;
import java.util.concurrent.Exchanger;/*** 消费者对象 先同步交换,再消费。* * @author jangle* @email jangle@jangle.xyz* @time 2020年8月13日 下午8:02:00* */
public class Consumer implements Runnable {private List<String> buffer;private final Exchanger<List<String>> exchanger;public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) {super();this.buffer = buffer;this.exchanger = exchanger;}@Overridepublic void run() {for (int i = 1; i < 10; i++) {System.out.println("消费者开始第" + i + "轮消费");try {buffer = exchanger.exchange(buffer);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("消费者完成交换,交换后列表大小:" + buffer.size() + ",对象:" + buffer);System.out.println("消费者开始消费");for (int j = 0; j < 10; j++) {String string = buffer.get(0);System.out.println("消费:" + string);buffer.remove(0);}}}}
四、执行结果
生产者第1期
消费者开始第1轮消费
生产:10
生产:11
生产:12
生产:13
生产:14
生产:15
生产:16
生产:17
生产:18
生产:19
生产者:交换后的缓冲区列表大小:0对象:[]
生产者第2期
生产:20
生产:21
消费者完成交换,交换后列表大小:10,对象:[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
消费者开始消费
生产:22
生产:23
生产:24
生产:25
生产:26
生产:27
生产:28
消费:10
生产:29
消费:11
消费:12
消费:13
消费:14
消费:15
消费:16
消费:17
消费:18
消费:19
消费者开始第2轮消费
生产者:交换后的缓冲区列表大小:0对象:[]
生产者第3期
消费者完成交换,交换后列表大小:10,对象:[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
消费者开始消费
生产:30
消费:20
生产:31
消费:21
生产:32
消费:22
生产:33
消费:23
生产:34
消费:24
生产:35
消费:25
生产:36
消费:26
生产:37
消费:27
生产:38
消费:28
生产:39
消费:29
消费者开始第3轮消费
生产者:交换后的缓冲区列表大小:0对象:[]
消费者完成交换,交换后列表大小:10,对象:[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
消费者开始消费
生产者第4期
消费:30
生产:40
生产:41
消费:31
生产:42
消费:32