目录
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;
}
@Override
public 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;
}
@Override
public 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

本文深入探讨了Java并发API中的Exchanger工具类,通过一个生产者-消费者案例,详细讲解了如何使用Exchanger实现两个线程之间的数据交换。案例中,生产者与消费者各自独立工作,通过Exchanger在指定的同步点交换数据结构。
1271

被折叠的 条评论
为什么被折叠?



