在Java平台,实现异步调用的角色有如下三个角色:调用者、 提货单 、真实数据,一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单

.然后在过一断时间后凭提货单来获取真正的数据.去蛋糕店买蛋糕,不需要等蛋糕做出来(假设现做要很长时间),只需要领个提货单就可以了(去干别的

事情),等到蛋糕做好了,再拿提货单取蛋糕就可以了。

package com.somnus.async;  /** *  * @Description: 顾客 * @author Somnus * @date 2016年3月9日 下午7:20:41 * @version 1.0 */
public class Customer {  public static void main(String[] args) {  System.out.println("main BEGIN");  CakeShop host = new CakeShop();  Cake cake1 = host.request(10, 'A');  Cake cake2 = host.request(20, 'B');  Cake cake3 = host.request(30, 'C');  System.out.println("main otherJob BEGIN");  try {  Thread.sleep(2000);  } catch (InterruptedException e) {  }  System.out.println("main otherJob END");  System.out.println("cake1 = " + cake1.getCake());  System.out.println("cake2 = " + cake2.getCake());  System.out.println("cake3 = " + cake3.getCake());  System.out.println("main END");  }
}  

这里的Customer类就相当于“顾客”,CakeShop就相当于“蛋糕店”,顾客向“蛋糕店”定蛋糕就相当于“发请求request”,返回的数据cake是

DeliveryOrder的实例,就相当于提货单,而不是真正的“蛋糕”。在过一段时间后(sleep一段时间后),调用data1.getContent(),也就是拿提货单获取

执行结果。

  下面来看一下,顾客定蛋糕后,蛋糕店做了什么:

package com.somnus.async;  /** * @Description: TODO * @author Somnus * @date 2016年3月9日 下午7:21:32 * @version 1.0 */
public class CakeShop {  public Data request(final int count, final char c) {  System.out.println("request(" + count + ", " + c + ") BEGIN");  // (1) 建立DeliveryOrder的实体  final DeliveryOrder order = new DeliveryOrder();  // (2) 为了建立RealData的实体,启动新的线程  new Thread() {  public void run() {  //在匿名内部类中使用count、order、c。  CakeBaker cakeBaker = new CakeBaker(count, c);  order.setCakeBaker(cakeBaker);  }  }.start();  System.out.println("request(" + count + ", " + c + ") END");  // (3) 取回FutureData实体,作为传回值  return order;  }
}  

CakeShop("蛋糕店")在接到请求后,先生成了“提货单”DeliveryOrder的实例order,然后命令“蛋糕师傅CakeBaker去做蛋糕,CakeBaker相当于起

个线程去做蛋糕了。然后host返回给顾客的仅仅是“提货单”future,而不是蛋糕。当蛋糕做好后,蛋糕师傅才能给对应的“提货单”蛋糕,也就

是order.setCakeBaker(cakeBaker);。

  下面来看看蛋糕师傅是怎么做蛋糕的:

  建立一个字符串,包含count个c字符,为了表现出犯法需要花费一些时间,使用了sleep。

package com.somnus.async;  /** * @Description: 蛋糕师傅 * @author Somnus * @date 2016年3月9日 下午7:22:52 * @version 1.0 */
public class CakeBaker implements Cake {  private final String cake;  public CakeBaker(int count, char c) {  System.out.println("making cake(" + count + ", " + c + ") BEGIN");  char[] buffer = new char[count];  for (int i = 0; i < count; i++) {  buffer[i] = c;  try {  Thread.sleep(3000);  } catch (InterruptedException e) {  e.printStackTrace();  }  }  System.out.println("making cake(" + count + ", " + c + ") END");  this.cake = new String(buffer);  }  public String getCake() {  return cake;  }  } 

现在来看看“提货单”order是怎么与蛋糕"cake"对应的:

package com.somnus.async;  /** * @Description: 提货单 * @author Somnus * @date 2016年3月9日 下午7:25:06 * @version 1.0 */
public class DeliveryOrder implements Cake {  private CakeBaker cakeBaker = null;  private boolean ready = false;  public synchronized void setCakeBaker(CakeBaker cakeBaker) {  if (ready) {  return; // 防止setCakeBaker被调用两次以上。  }  this.cakeBaker = cakeBaker;  this.ready = true;  notifyAll();  }  public synchronized String getCake() {  while (!ready) {  try {  wait();  } catch (InterruptedException e) {  e.printStackTrace();  }  }  return cakeBaker.getCake();  }  }

顾客做完自己的事情后,会拿着自己的“提货单”来取蛋糕:


System.out.println("cake1 = " + cake1.getCake());

这时候如果蛋糕没做好,就只好等了:


while (!ready) {  try {  wait();  } catch (InterruptedException e) {  e.printStackTrace();  }
}  

//等做好后才能取到

return cakeBaker.getCake();  

程序分析

  对于每个请求,host都会生成一个线程,这个线程负责生成顾客需要的“蛋糕”。在等待一段时间以后,如果蛋糕还没有做好,顾客还必须等待。

直到“蛋糕被做好”,也就是

  order.setCakeBaker(cakeBaker);执行以后,顾客才能拿走蛋糕。

  每个线程只是专门负责制作特定顾客所需要的“蛋糕”。也就是顾客A对应着蛋糕师傅A,顾客B对应着蛋糕师傅B。即使顾客B的蛋糕被先做好了,

顾客A也只能等待蛋糕师傅A把蛋糕做好。换句话说,顾客之间没有竞争关系。

  类DeliveryOrder的两个方法被设置为synchronized,实际上蛋糕师傅A与顾客A之间的互斥关系,也就是顾客A必须等待蛋糕师傅A把蛋糕做好后,

才能拿走,而与蛋糕师傅B是否做好了蛋糕没有关系。

https://blog.csdn.net/xlgen157387/article/details/78390642

https://www.cnblogs.com/tuojunjie/p/6836677.html

java 多线程 异步调用相关推荐

  1. java多线程异步调用别的系统接口代码_抢先准备,40个 Java 多线程面试题及答案大汇总!...

    ↑↑↑点上方蓝字关注并标⭐「IT技术思维」 一起培养顶尖技术思维 来源:程序员共成长(id:finishbug) 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有 ...

  2. java多线程异步调用别的系统接口代码_60 多个实例讲解,彻底搞懂 Java 多线程!

    ​JAVA 最难学的部分是哪里?很多朋友都会说:「 java 多线程 」. 随着业务量和数据的增加,企业不可避免地会使用多线程的方式处理数据.在 Java 职位的面试中,多线程也是必考的高阶知识点之一 ...

  3. java 多异步调用_java 异步调用与多线程

    异步与多线程的区别 一.异步和多线程有什么区别?其实,异步是目的,而多 线程是实现这个目的的方法.异步是说,A发起一个操作后(一般都是比较耗时的操作,如果不耗时的操作 就没有必要异步了),可以继续自顾 ...

  4. java http异步调用_HttpClient的异步调用,你造吗?

    一.前言 HttpClient提供了两种I/O模型:经典的java阻塞I/O模型和基于Java NIO的异步非阻塞事件驱动I/O模型. Java中的阻塞I/O是一种高效.便捷的I/O模型,非常适合并发 ...

  5. java实现异步调用实例

    在JAVA平台,实现异步调用的角色有如下三个角色:   调用者 取货凭证   真实数据   一个调用者在调用耗时操作,不能立即返回数据时,先返回一个取货凭证.然后在过一断时间后凭取货凭证来获取真正的数 ...

  6. java同步异步调用_详解java 三种调用机制(同步、回调、异步)

    1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,jsPwwCe它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消 ...

  7. java thrift异步调用_thrift异步调用 - thrift-cob_style-tnonblockingserver - ItBoth

    [ thrift 在python中使用了 tornado和  twisted 来作为异步的webserive服务提供异步接口,自身并没有实现     twisted:         Generate ...

  8. Java线程异步调用使用的最好的方式

    一.异步调用方式分析 今天在写代码的时候,想要调用异步的操作,这里我是用的java8的流式异步调用,但是使用过程中呢,发现这个异步方式有两个方法,如下所示: 区别是一个 需要指定线程池,一个不需要. ...

  9. java 多线程 异步日志_精彩技巧(1)-- 异步打印日志的一点事

    一.前言 最近刚刚结束转岗以来的第一次双11压测,收获颇多,难言言表, 本文就先谈谈异步日志吧,在高并发高流量响应延迟要求比较小的系统中同步打日志已经满足不了需求了,同步打日志会阻塞调用打日志的线程, ...

  10. 【java】java 多线程 异步计算 FutureTask 源码详解

    1.概述 扩展阅读:[java]线程 ExecutorService 原理 源码 解释 1.1 问题 FutureTask用来解决什么问题的? 为什么会出现? FutureTask类结构关系怎么样的? ...

最新文章

  1. 设置CentOS 6.6系统默认的语言为中文
  2. DELPHI FMX 获取系统版本 ANDROID IOS通用
  3. java 如何把源码导出为jar包,以及如何使用导出的jar包
  4. 类的定义、成员定义修饰符
  5. linux安装python3.7的步骤_Linux 安装python3.7.3
  6. NandFlash启动理解(S3C2410)
  7. 能帮你快速设计好APP的UI kits套装
  8. Libev源码分析07:Linux下的eventfd简介
  9. Jenkins问题:SVN插件未更新到最新代码
  10. 项目成本管理:成本与成本管理概念
  11. 网易云精选评论,总有一句戳在你心里
  12. 谈谈 MVX 中的 Controller
  13. 谈谈在ISA防火墙中的端口映射方法
  14. 学生成绩管理系统html代码,学生成绩管理系统(含源代码)30.doc
  15. 根据身份证号和社会保险号码查询不出您的医保信息 请核实后重新填写
  16. 高中OJ3837. 【NOIP2014模拟9.14】心灵终结
  17. 技术的真相 | 从AR口红试妆了解人工智能试妆技术
  18. 中英文在线语音转文字的方法
  19. 2018百度之星程序设计大赛资格赛(4道题的答案)
  20. 导航坐标系:地心惯性坐标系、地心地固坐标系、当地水平坐标系、载体/机体坐标系

热门文章

  1. 常用iOS游戏开发工具与SDK
  2. 在 github 上建立 pages 的过程
  3. 零基础学习嵌入式给出的10条中肯的建议
  4. 数据库 char nchar varchar nvarchar 区别
  5. 一个容易失误的字符串转字符问题
  6. 拓端tecdat|R语言空气污染数据的地理空间可视化和分析:颗粒物2.5(PM2.5)和空气质量指数(AQI)
  7. (3)数据结构-线性表链式存储
  8. 2-9 装箱问题 (20 分)
  9. 4月升级鸿蒙,华为鸿蒙系统4月升级适配名单一览
  10. js基础知识汇总01