并发编程:线程同步工具:5、Exchanger 两个并发任务间的数据交换

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

目录

 

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;
	}

	@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

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值