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

所以连结调用者和真实数据之间的桥梁是取货凭证.我们先来看它的实现:

public class FutureTicket{
 private Object data = null;
 private boolean completed = false;

 public synchronized void makeRealData(){
  if(this.complited) return;
  //获取数据的耗时操作.这里用Sleep代替
  try{
   Thread.sleep(10000);
  }catch(Throwable t){}
  this.data = "返回的数据内容";
  this.completed = true;
  notifyAll();
 }

 public synchronized Object getData(){
  while(!this.completed)){
   try{
    wait();
   }catch(Throwable t){}
  }
  return this.data;

 }
 public boolean isCompleted(){
  return this.completed;
 }
}

为了简单化说明(不把它们的关系开得复杂),这里用Objectb代替了真实数据.而真实的实现中我们应该把makeData放在一个真实数据的类中,然后提供一个方法返回真实数据.这样对于真实数据的处理和取货凭证解耦.
 
对于这个取货凭证,调用者的如何调用是异步调用的关键:

publc class Requester{
 public FutureTicket request(){
  final FutureTicket ft = new FutureTicket();

  //在新线程中调用耗时操作
  new Thread(){
   public void run(){
    ft.makeRealData();
   }
  }.start();
  return ft;
 }
}

在新线程中启动耗时操作后,不等待线程的完成立即返回提货单.
 
然后调用者可以根据ft.isCompleted()来调用getData()获取真实数据.当然对ft.isCompleted()测试可以按规定时间间隔轮巡(极低级的方案),也可以在条件不满足时wait(),然后等待makeData的notifyAll();这样你就完成了一个用JAVA模拟的异步操作.
 

改进:
但这样的调用对于调用者来说仍然要继续控制线程操作.如果调用者是一个资深的程序员,这当然没有问题.但假如我们把对直接数据的处理委托给取货凭证来做.调用者直接规定对数据的操作,然后由取货凭证来调用规定的操作,这对于调用者是一个很好的解脱:

interface ProcessData{
 public void process(Onject data);
}

public MyProcessData{
 public void process(Object data){
  //你不管什么时候起初数据data被获取了.
  //你只要规定如果获取到数据了如何处理

  System.out.println(data.toString() + "处理完成...........");
  //insert into dataBase?
 }
}

取货凭证在接收调用者请求获取数据时,要知道对获取的数据如何处理的方法:

public class FutureTicket{
 private Object data = null;
 private boolean completed = false;
 private ProcessData pd;

 public FutureTicket(ProcessData pd){
  this.pd = pd;
 }
 public synchronized void makeRealData(ProcessData pd){
  if(this.complited) return;
  //获取数据的耗时操作.这里用Sleep代替
  try{
   Thread.sleep(10000);
  }catch(Throwable t){}
  this.data = "返回的数据内容";
  this.completed = true;
  notifyAll();
 }

 public synchronized void putData(){
  while(!this.completed)){
   try{
    wait();
   }catch(Throwable t){}
  }
  //return this.data;
  //不用返回了,直接处理
  this.pd.process(this.data);
  // alert(?);

 }

 //这个方法也可以不要了.
 public boolean isCompleted(){
  return this.completed;
 }
}

调用:

  final FutureTicket ft = new FutureTicket(new ProcessData());

  //在新线程中调用耗时操作
  new Thread(){
   public void run(){
    ft.makeRealData();
   }
  }.start();
  ft.putData();

OK,你现在可以抽烟,喝酒,泡妞.ft会为你完成所有的工作.

java实现异步调用实例的更多相关文章

  1. 利用回调实现Java的异步调用

    异步是指调用发出后,调用者不会立刻得到结果,而是在调用发出后,被调用者通知调用者,或通过回调函数处理这个调用. 回调简单地说就是B中有一个A,这样A在调用B的某个方法时实际上是调用到了自己的方法. 利 ...

  2. .NET中的async和await关键字使用及Task异步调用实例

    其实早在.NET 4.5的时候M$就在.NET中引入了async和await关键字(VB为Async和Await)来简化异步调用的编程模式.我也早就体验过了,现在写一篇日志来记录一下顺便凑日志数量(以 ...

  3. C#_delegate - 异步调用实例 BeginInvoke EndInvoke event

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. Java 实现异步调用

    首先 我遇到的问题是 接口调用时需要更新缓存 而更新缓存又是个说快不快的过程 所以打算做异步调用 返回我所需要的结果即可 ,至于缓存什么时候更新完 就不是我所需要关注的了 废话不多说 上代码 publ ...

  5. 功能完善的Java连接池调用实例

    /** * Title: ConnectPool.java * Description: 连接池管理器 * Copyright: Copyright © 2002/12/25 * Company: * ...

  6. java中异步调用注意

    Future接口是Java标准API的一部分,在java.util.concurrent包中.Future接口是Java线程Future模式的实现,可以来进行异步计算. 有了Future就可以进行三段 ...

  7. Java实现异步调用

    一.创建线程 @Test public void test0() throws Exception { System.out.println("main函数开始执行"); Thre ...

  8. java中异步调用的解决方法

    package demo.future; import java.util.ArrayList; import java.util.List; import java.util.concurrent. ...

  9. 5种必会的Java异步调用转同步的方法你会几种

    转载请注明本文地址:https://www.jianshu.com/p/f00aa6f66281 源码地址:https://gitee.com/sunnymore/asyncToSync Sunny先 ...

随机推荐

  1. 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法

    在SQL数据库中使用SQL语句(格式:alter table [tablename] alter column [colname] [newDataType])修改某表的字段类型时,报一下错误:由于一 ...

  2. java线程池的使用

    一.简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.uti ...

  3. ios html5 audio 不能自动播放

    //修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio 用的时候更换src即可 Xut.fix = Xut.fix||{}; if (Xut.plat.isBrowser & ...

  4. 在java中如何使用etcd的v2 和v3 api获取配置,并且对配置的变化进行监控

    etcd 和zookeeper 很像,都可以用来做配置管理.并且etcd可以在目前流行的Kubernetes中使用. 但是etcd 提供了v2版本合v3的版本的两种api.我们现在分别来介绍一下这两个 ...

  5. Python中and(逻辑与)计算法则

    在程序设计中,and称为逻辑与运算,也称布尔运算:1.and是在布尔上下文中从左到右计算表达式的值:2.0.''.[].().{}.None.False在布尔上下文中为假:其它任何东西都为真:3.如果 ...

  6. python脚本批量生成数据

    在平时的工作中,经常会遇到造数据,特别是性能测试的时候更是需要大量的数据.如果一条条的插入数据库或者一条条的创建数据,效率未免有点低.如何快速的造大量的测试数据呢?在不熟悉存储过程的情况下,今天给大家 ...

  7. UltraISO安装centos7系统

    1. 使用最新版UltraISO将ISO镜像刻录到U盘一定要是最新版,试用版都可以,按下图操作: 2. U盘启动电脑进入安装界面正常情况下你应该会看到下面的这个界面: 选择第一项,然后按TAB键(在评 ...

  8. RunLoop总结:RunLoop 与GCD 、Autorelease Pool之间的关系

    如果在面试中问到RunLoop相关的知识,很有可能也会问到RunLoop与GCD.Autorelease Pool有没有关系,哪些地方用到了GCD.Autorelease Pool等. So,本文就总 ...

  9. 安卓高级Fresco图片框架的时候

    Fresco:2015FaceBook推出的 及其强大 支持webp图片格式 和渐进式图片加载 中文文档 使用方法 引入依赖 点击查看具体教程 基本使用步骤 在布局中使用其标签 <com.fac ...

  10. Android5.0特性ToolBar

    >Toolbar是什么?大概说一下它的官方介绍.Toolbar是应用的内容的标准工具栏,`可以说是Actionbar的升级版`,两者不是独立关系,要使用Toolbar还是得跟ActionBar扯 ...