【原】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 ec = new Exchanger();

ExecutorService es = Executors.newFixedThreadPool(2);

es.submit(new Waiter(ec,cup2));

es.submit(new Drinker(ec, cup1));

es.shutdown();

}

}

exchange java对象,【原】Java并发程序的一个应用Exchanger的实例相关推荐

  1. Redis存储java对象或者java对象数组

    1. 先将java对象或者java对象数组用ObjectMapper转换为json对象 2. 再用jedis对象的put方法,将数据写入Redis数据库

  2. java对象组合_java并发编程(三): 对象的组合

    对象的组合: 如何将现有的线程安全组件,组合成我们想要的更大规模的程序. 设计线程安全的类: 设计线程安全类的三个要素: 1.找出构成对象状态的所有变量: 2.找出约束状态变量的不变性条件: 3.建立 ...

  3. java 多线程 同步 观察者 并发集合的一个例子

    //第一版 package com.hra.riskprice;import com.hra.riskprice.SysEnum.Factor_Type; import org.springframe ...

  4. java 对象protected,Java对象类protected void finalize throws Throwable方法示例

    对象类保护的voidfinalize() throws Throwable此方法在java.lang.Object.finalize()中可用. 当不再有引用保留时,垃圾回收器将调用此方法. 此方法对 ...

  5. JAVA对象转为Java String的几种常用方法

    在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object#toString(),(String)要转换的对象,St ...

  6. android java广播,[原]Android应用程序发送广播(sendBroadcast)的过程分析

    前面我们分析了Android应用程序注册广播接收器的过程,这个过程只完成了万里长征的第一步,接下来它还要等待ActivityManagerService将广播分发过来.ActivityManagerS ...

  7. Java对象在Java虚拟机的创建过程

    创建 1.相应类加载检查过程 Java程序中的"new"操作会转换为Class文件中方法的"new"字节码指令. JVM(本文特指HotSpot)遇到new指令 ...

  8. java对象序列化java.io.Serializable 接口实践

    java.io.Serializable 接口没有任何方法和字段,仅仅表示实现它的类的对象可以被序列化.实现了这个接口的所有类及其子类都可以对象序列化. 序列化前,虚拟机要清楚每个对象的结构,所以序列 ...

  9. php序列化 java对象,在Java中反序列化一个序列化的php对象

    Does anyone know if it is possible, actually if it has been done, to serialize an object in php and ...

最新文章

  1. Git 修改用户名和邮箱
  2. rsyncd.conf 详细配置
  3. 用html编写一幅简单的画,使用html5画简单的折线图
  4. 吴恩达深度学习编程作业:TensorFlow
  5. 80 后技术人的中年危机
  6. 22. 栈的压入、弹出队列(C++版本)
  7. Go语言:基础数据类型
  8. 南方cass字体样式设置_cass怎么修改字体 cass字体样式管理器
  9. 手机识别图片文字的方法
  10. 大一想去参加培训的学生
  11. 使用python实现自动爬取得物交易记录,商品信息进行数据分析
  12. 弘辽科技:拼多多24小时不发货怎么办?如何发货?
  13. 国内数字藏品的乱象与未来
  14. 2021年德阳2中高考成绩查询,2021年德阳高中录取分数线是多少及高中排名榜
  15. 记录一次租房经历一(1)
  16. 解决锁定图层后不能淡显的问题
  17. 涤纶电容的作用原理及优点缺点
  18. python-自动化运维、办公、爬虫和娱乐
  19. Spring MVC基础四
  20. 文本(文章内容)编辑器(CMS管理)

热门文章

  1. Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠)
  2. 搭建: canal部署与实例运行
  3. java或异运算_java中与运算,或运算,异或运算,取反运算
  4. arraylist 的扩容机制_每天都用ArrayList,你读过它的源码么?
  5. 计算机管理中添加用户属性,如何在计算机右键菜单栏中添加属性选项
  6. 商城html源码_Java开源商城源码推荐,从菜鸡到大神,永远绕不开的商城系统
  7. python的变量名有哪些_【python字符串做变量名的方法有哪些?这些方法对python应用很重要】- 环球网校...
  8. 【LeetCode笔记】剑指 Offer 44. 数字序列中某一位的数字(Java、偏数学)
  9. python写前端和js_Python之路【第十二篇】前端之jsdomejQuery
  10. 内存条能4+8混插吗?_笔记本内存条双通道提升有多大?实测FORESEE,你知道好处在哪吗...