`

java多线程编程——同步器Exchanger(四)

阅读更多
类java.util.concurrent.Exchanger提供了一个同步点,在这个同步点,一对线程可以交换数据。每个线程通过exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程提供的数据,并返回。
当在运行不对称的活动时很有用,比如当一个线程填充了buffer,另一个线程从buffer中消费数据的时候,这两个线程可以用Exchanger来交换数据。当两个线程通过Exchanger交换数据的时候,这个交换对于两个线程来说是线程安全的。两个线程都会等到自己的程序运行到Exchanger这个地方时,进行等待。然后再进行数据交换,交换完毕后,各自进行以后的程序流程。


以下这个程序demo要做的事情就是生产者在交换前生产5个"生产者",然后再与消费者交换5个数据,然后再生产5个"交换后生产者",而消费者要在交换前消费5个"消费者",然后再与生产者交换5个数据,然后再消费5个"交换后消费者"。
package test;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Exchanger;

/**
 * 两个线程间的数据交换
 *
 * @author Administrator
 *
 */
@SuppressWarnings("all")
public class ExchangerDemo {

	private static final Exchanger ex = new Exchanger();

	class DataProducer implements Runnable {
		private List list = new ArrayList();

		public void run() {
			System.out.println("生产者开始运行");
			System.out.println("开始生产数据");
			for (int i = 1; i <= 5; i++) {
				System.out.println("生产了第" + i + "个数据,耗时1秒");
				list.add("生产者" + i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("生产数据结束");
			System.out.println("开始与消费者交换数据");
			try {
				// 将数据准备用于交换,并返回消费者的数据
				list = (List) ex.exchange(list);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("结束与消费者交换数据");
			System.out.println("生产者与消费者交换数据后,再生产数据");
			for (int i = 6; i < 10; i++) {
				System.out.println("交换后生产了第" + i + "个数据,耗时1秒");
				list.add("交换后生产者" + i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("开始遍历生产者交换后的数据");
			// 开始遍历生产者的数据
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				System.out.println(iterator.next());
			}
		}
	}

	class DataConsumer implements Runnable {
		private List list = new ArrayList();

		public void run() {
			System.out.println("消费者开始运行");
			System.out.println("开始消费数据");
			for (int i = 1; i <= 5; i++) {
				System.out.println("消费了第" + i + "个数据");
				// 消费者产生数据,后面交换的时候给生产者
				list.add("消费者" + i);
			}
			System.out.println("消费数据结束");
			System.out.println("开始与生产者交换数据");
			try {
				// 进行数据交换,返回生产者的数据
				list = (List) ex.exchange(list);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("消费者与生产者交换数据后,再消费数据");
			for (int i = 6; i < 10; i++) {
				System.out.println("交换后消费了第" + i + "个数据");
				list.add("交换后消费者" + i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("开始遍历消费者交换后的数据");
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				System.out.println(iterator.next());
			}
		}
	}

	public static void main(String args[]) {
		ExchangerDemo et = new ExchangerDemo();
		new Thread(et.new DataProducer()).start();
		new Thread(et.new DataConsumer()).start();
	}
}


执行结果

    生产者开始运行
    开始生产数据
    生产了第1个数据,耗时1秒
    消费者开始运行
    开始消费数据
    消费了第1个数据
    消费了第2个数据
    消费了第3个数据
    消费了第4个数据
    消费了第5个数据
    消费数据结束
    开始与生产者交换数据
    生产了第2个数据,耗时1秒
    生产了第3个数据,耗时1秒
    生产了第4个数据,耗时1秒
    生产了第5个数据,耗时1秒
    生产数据结束
    开始与消费者交换数据
    消费者与生产者交换数据后,再消费数据
    交换后消费了第6个数据
    结束与消费者交换数据
    生产者与消费者交换数据后,再生产数据
    交换后生产了第6个数据,耗时1秒
    交换后消费了第7个数据
    交换后生产了第7个数据,耗时1秒
    交换后消费了第8个数据
    交换后生产了第8个数据,耗时1秒
    交换后消费了第9个数据
    交换后生产了第9个数据,耗时1秒
    开始遍历消费者交换后的数据
    生产者1
    生产者2
    生产者3
    生产者4
    生产者5
    交换后消费者6
    开始遍历生产者交换后的数据
    交换后消费者7
    交换后消费者8
    消费者1
    交换后消费者9
    消费者2
    消费者3
    消费者4
    消费者5
    交换后生产者6
    交换后生产者7
    交换后生产者8
    交换后生产者9


分享到:
评论

相关推荐

    Java编程线程同步工具Exchanger的使用实例解析

    主要介绍了Java编程线程同步工具Exchanger的使用实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    Java多线程编程之使用Exchanger数据交换实例

    主要介绍了Java多线程编程之使用Exchanger数据交换实例,本文直接给出实例代码,需要的朋友可以参考下

    Java多线程同步器代码详解

    主要介绍了Java多线程同步器代码详解,文章分别介绍了是CountDownLatch,Semaphore,Barrier和Exchanger以及其相关代码示例,具有一定参考价值,需要的朋友可以了解下。

    java并发Exchanger的使用

    Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的。这里主要是两个线程之间交换持有的对象。当Exchanger在一个线程中调用exchange方法之后,会等待另外的线程调用同样的exchange方法。 两个线程都...

    【2018最新最详细】并发多线程教程

    【2018最新最详细】并发多线程教程,课程结构如下 1.并发编程的优缺点 2.线程的状态转换以及基本操作 3.java内存模型以及happens-before规则 4.彻底理解synchronized 5.彻底理解volatile 6.你以为你真的了解final吗...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、介绍三种高效优雅的Singleton实现方式.wmv │ 高并发编程第二阶段04讲、多线程的休息室WaitSet详细...

    Java并发编程原理与实战

    了解多线程所带来的安全风险.mp4 从线程的优先级看饥饿问题.mp4 从Java字节码的角度看线程安全性问题.mp4 synchronized保证线程安全的原理(理论层面).mp4 synchronized保证线程安全的原理(jvm层面).mp4 单例问题...

    龙果 java并发编程原理实战

    龙果 java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、介绍三种高效优雅的Singleton实现方式.wmv │ 高并发编程第二阶段04讲、多线程的休息室WaitSet详细...

    Java并发编程(学习笔记).xmind

    (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程...

    Java JDK实例宝典

    7 一个支持多线程的服务器框架 13. 8 代理服务器 13. 9 Telnet客户端 13. 10 UDP编程 13. 11 聊天室服务器端 13. 12 聊天室客户端 13. 13 FTP客户端 第14章 数据库 14. 1 连接各种...

    Java 并发编程原理与实战视频

    java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个...

    尚硅谷——java.util.concurrent和工具类

    一、java.util.concurrent体系的主要大板块包含内容 二、Executors 三、Semaphor信号量 四、Exchanger线程交互 五、CyclicBarrier关卡模式 六、CountDownLatch计数器

    龙果java并发编程完整视频

    第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...

    Java:Exchanger类的作用.docx

    java.util.concurrent包中的Exchanger类可用于两个线程之间交换信息。可简单地将Exchanger对象理解为一个包含两个格子的容器,通过exchanger方法可以向两个格子中填充信息。当两个格子中的均被填充时,该对象会自动...

    java线程并发semaphore类示例

    Java 5.0里新加了4个协调线程间进程的同步装置,它们分别是Semaphore, CountDownLatch, CyclicBarrier和Exchanger,本例主要介绍Semaphore,Semaphore是用来管理一个资源池的工具,可以看成是个通行证

    java jdk实列宝典 光盘源代码

    一个支持多线程的服务器框架,GeneralServer.java; 代理服务器,ProxyServer.java; telnet客户端,访问系统的telnet服务实质上是与telnet服务建立socket连接,默认的telnet服务的端口是23,TelnetClient.java; ...

    java并发工具类(CountDownLatch+Semaphore+Exchanger)

    java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+...

    JAVA并发编程-2-线程并发工具类

    JAVA并发编程-2-线程并发工具类一、Fork/Join1、分而治之与工作密取2、使用标准范式3、Fork/Join的同步用法4、Fork/Join的异步用法二、CountDownLatch三、CyclicBarrier四、Semaphore信号量五、Exchanger ...

Global site tag (gtag.js) - Google Analytics