`

【原】Java并发程序的一个使用Exchanger的实例

 
阅读更多

今天看了些Exchanger的资料,有个喝水的例子不错。我这里细化了以下,并得到实现。

 

思路:

 

     有一个Drinker和一个Waiter,有两个杯子,一个空杯子,一个杯子有3升水,Drinker一次喝1升水,要耗时1秒,Waiter一次可以倒1升水,一次耗时1秒。开始时,他们各持一个杯子,Drinker持有3升水的杯子,Waiter持有空杯子。然后开始喝水,当有一个杯子里没水了,整个程序结束。

 

方法:

 

     Exchanger主要用于交换两个线程的同类型的共享数据,喝水这个例子很好的表现了Exchanger的作用。

 

【注:】程序中的数据可以自己调整来,整体体现了动态交换杯子的效果。

 

 

 

 

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Cup {
	
	int waterVolume = 0;
	
	String cupName="";
	public String getCupName() {
		return cupName;
	}
	
	public void setCupName(String cupName) {
		this.cupName = cupName;
	}
	Cup(int i ,String name){
		waterVolume=i;
		cupName=name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return cupName+"有"+waterVolume+"升水!";
	}
	public int getWaterVolume() {
		return waterVolume;
	}
	public void drinkWater(){
		waterVolume--;
	}
	public void drinkWater( int i ){
		if((waterVolume-i)>=0){
		   waterVolume-=i;
		}else{
			System.out.println("没有这么多水可以喝!!!");
			return;
		}
	}
	public void addWater(){
		waterVolume++;
	}
	public void addWater(int i){
		waterVolume=i;
	}
}

class Drinker implements Runnable{
	Cup currentCup;
	Exchanger ex;
	Drinker(Exchanger ex,Cup c){
		currentCup= c;
		this.ex= ex;
	}
	@Override
	public void run() {
		//得到杯子喝水
		/*try {
			currentCup = (Cup)ex.exchange(currentCup);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}*/
		boolean flag = true;
		while(flag){
			if(currentCup.getWaterVolume() > 0){
				System.out.println("喝水者:"+currentCup);
				System.out.println("喝水者:从"+currentCup.getCupName()+"喝2升水,喝水用时1秒");
				currentCup.drinkWater(2);
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
			if(currentCup.getWaterVolume() == 0){
				System.out.println("喝水者:"+currentCup+",水喝光了!别加了!");
				flag=false;
			}
			//服务员加完水后的杯子
			try {
				currentCup = (Cup)ex.exchange(currentCup);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
}

class Waiter implements Runnable{
	Cup currentCup;
	Exchanger ex;
	Waiter(Exchanger ex,Cup c){
		currentCup= c;
		this.ex= ex;
	}
	@Override
	public void run() {
		//得到杯子加水
		/*try {
			currentCup = (Cup)ex.exchange(currentCup);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}*/
		boolean flag = true;
		while(flag){
			System.out.println("服务员:"+currentCup);
			System.out.println("服务员:倒入"+currentCup.getCupName()+"  1升水,耗时1秒");
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			currentCup.addWater();
			//得到顾客递过来的杯子
			try {
				currentCup=(Cup)ex.exchange(currentCup);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(currentCup.getWaterVolume() == 0){
				System.out.println("服务员:"+currentCup+"水喝光了!!不加了!");
				flag=false;
			}
		}
		
	}
}


public class DrinkWaterDemo {
	public static void main(String[] args) {
		Cup cup1 = new Cup(3,"cup1");
		Cup cup2 = new Cup(0,"cup2");
		final Exchanger<Cup> ec = new Exchanger<Cup>();
		ExecutorService es = Executors.newFixedThreadPool(2);
		es.submit(new Waiter(ec,cup2));
		es.submit(new Drinker(ec, cup1));
		es.shutdown();
		
	}
}

 

分享到:
评论

相关推荐

    Java 并发编程实战(高清带目录).zip

    详细讲解了Java并发库中的关键类和接口,如Thread、Runnable、ExecutorService、Future、Semaphore、CyclicBarrier、CountDownLatch、Exchanger以及Lock(ReentrantLock、ReadWriteLock)等,这些都是Java并发编程中...

    java并发之并发工具类

    在创建 CountDownLatch 实例时,需要传递一个 int 型的参数:count,该参数为计数器的初始值,也可以理解为该共享锁可以获取的总次数。当某个线程调用 await() 方法,程序首先判断 count 的值是否为 0,如果不会 0 ...

    java并发工具类

    Java并发工具类是Java平台提供的一系列用于处理多线程并发问题的类和接口,它们在`java.util.concurrent`包中。并发问题主要包括资源竞争、死锁、活锁以及饥饿等,合理使用并发工具可以有效地提高程序的并发性能并...

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

    Java多线程编程中的Exchanger是一个非常有用的工具类,它位于`java.util.concurrent`包下,主要用于线程间的数据交换。Exchanger的核心功能是让两个线程在一个同步点相遇,进行数据交换。当一个线程调用`exchange`...

    实战Java高并发程序设计.mobi.azw3.epub

    《实战Java高并发程序设计》是一本专注于Java并发编程的实战型书籍,旨在帮助开发者深入理解和熟练掌握在Java环境中处理高并发场景的关键技术与最佳实践。书中的内容涵盖了多线程编程、并发容器、同步机制、并发工具...

    29 一手交钱,一手交货—Exchanger详解.pdf

    在Java并发编程中,Exchanger是一个非常有用的工具类,它允许两个线程间进行数据交换。这个类在处理需要同步的交互式任务时特别有用,比如在多阶段处理或者需要线程间协作的情况。Exchanger的工作原理就像一个中介,...

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

    (3)简化异步事件的处理:服务器应用程序在接受来自多个远程客户端的请求时,如果为每个连接都分配一个线程并且使用同步IO,就会降低开发难度 (4)用户界面具备更短的响应时间:现代GUI框架中大都使用一个...

    java并发编程之同步器代码示例

    下面是一个使用CountDownLatch的示例代码: ```java public class CountDownLatchTest { private static final int THREAD_COUNT = 10; private static final CountDownLatch startSingal = new CountDownLatch(1...

    java高并发1

    线程池是Java并发编程中的重要工具,如ExecutorService,它可以有效管理和控制线程,避免频繁创建和销毁线程带来的开销,提高响应速度。JVM创建对象的过程包括类加载、内存分配、初始化等步骤。 在并发编程中,Java...

    java 并发编程

    一个程序在执行过程中可能会有多个执行路径,每条路径就是一个线程。 - **进程**:一个正在执行的程序被称为进程,每个进程都有自己独立的地址空间和资源。 - **操作系统调度**:操作系统负责调度和管理这些进程中的...

    通俗易懂学习java并发工具类-Semaphore,Exchanger

    总结,Semaphore和Exchanger都是Java并发编程中重要的工具类。Semaphore用于控制并发访问的资源数量,避免资源过度消耗;Exchanger则用于线程间的数据交换,实现高效的协作处理。掌握这两个工具类的使用,能帮助...

    深入解析Java多线程

    Java多线程是Java编程中的一个核心概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多线程技术是不可或缺的一部分,尤其是在服务器端应用、高并发处理和实时系统中。本文将...

    并发编程二进阶部分.rar

    Java的`synchronized`关键字和`ReentrantLock`可以用来解决这个问题,确保同一时间只有一个线程能执行售票操作。 3. **并发工具类**: Java并发包提供了一些强大的工具类,例如`Semaphore`(信号量)、`...

    javajdk1.7_51

    8. **并发工具的增强**:添加了新的并发工具类,如`ConcurrentHashMap`的改进,以及`Phaser`、`Exchanger`等,帮助开发者更高效地编写多线程程序。 9. **改进的JDBC**:JDBC 4.1引入了新的连接池规范,提升了数据库...

    JAVA编程模式与范例_高级应用开发

    - **单例模式**:确保一个类只有一个实例,并提供全局访问点。 - **工厂模式**:提供创建对象的最佳方式,抽象出实例化过程。 - **抽象工厂模式**:为创建一系列相关或相互依赖的对象提供接口。 - **建造者模式*...

    thread.zip--狂神多线程+juc

    《狂神多线程+juc》是一份针对Java并发编程深度学习的资源包,主要涵盖了Java多线程基础以及Java并发工具集(JUC)的高级应用。在Java编程中,多线程是提高程序效率、实现并发执行的重要手段,而JUC(Java ...

    JAVA集合、多线程

    2. **线程同步**:为了防止多线程环境下数据的不一致,Java提供了synchronized关键字,可以保证同一时刻只有一个线程访问同步代码块。此外,还有wait()、notify()和notifyAll()方法用于线程间通信。 3. **线程池**...

    Java开发实战从入门到精通视频教程下载第9章 多线程.zip

    多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算环境中,多线程编程已经成为开发者必备的技能之一。 一、多线程基础 Java中的多线程可以通过两种主要...

    某电信项目多线程同步数据实例

    "某电信项目多线程同步数据实例"的标题揭示了一个具体的应用案例,它表明在该电信项目中,开发团队使用了多线程技术来高效地同步和处理数据。描述中提到的“经生产测试,一分钟同步数据量20W”,这展示了该技术方案...

    java技术指南

    《Java技术指南》是一份面向Java程序员的综合技术文档,其涵盖了Java语言从基础到高级的多个方面,旨在帮助Java入门者和进阶者提升技能...文档通过丰富的实例和源码分析,为Java程序员提供了一个全面、深入的学习平台。

Global site tag (gtag.js) - Google Analytics