在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. [NOI2011]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 省选完挂.但是善良的教练今天丢了一套NOI2011给我们训练 6道题233(虽然一道题做过了,一道题普及组的都会,就算是4道吧) 熬了一天,总 ...

  2. C++函数式编程实现牛顿法

    In numerical analysis, Newton's method (also known as the Newton–Raphson method), named after Isaac ...

  3. python dataframe数据条件筛选

    一般情况下我们从一堆数据中选择我们获取想要的数据会通过一下方式: (1)创建链表或数组: (2)用for 循环遍历所有数据,将想要的存入链表或数组. 但是python中我们不需要这么做,我们可以用Pa ...

  4. UDA机器学习基础—误差原因

    1.模型误差产生的原因 (1)模型无法表示基本数据的复杂度,而造成偏差. (2)因模型对训练它所用到的数据过度敏感造成的方差. 2.由偏差造成的误差--准确率和欠拟合 有足够数据表示模型,但是由于模型 ...

  5. 使用webgl(three.js)搭建一个3D建筑,3D消防模拟——第三课

    项目背景 消防安全一直是各大都市关注的重要课题,在消防体系中,特别是高楼消防体系中,消防系统整体布控与监控,火情有效准确定位,防火器材定位,人员逃生路径规划,火情预警,消防演习都是特别重要的环节.所以 ...

  6. 携程Java后台开发三面面经

    前言 携程是我面试的第一个互联网公司,投递的岗位是后台开发实习生,总共面了三面,止步于人才库.中间兜兜转转,复杂的心理活动,不足与外人道也.唯有面试的技术部分与大家共享. 宣讲会完了之后有个手写代码的 ...

  7. 性能优化之mysql优化——慢查日志的开启方式和存储

    -- MySQL优化 -- mysql 慢查日志的开启方式和存储 -- 1) 查看mysql是否开启慢查询日志 SHOW VARIABLES LIKE 'slow_query_log'; -- 2) ...

  8. easyui datagrid 动态表头2

    前端 function goqry() { $("#form").form("submit", { url: "CJCK_bjcjfx_yfsl.as ...

  9. html学习中

    Html常用标签一 <body style="background-color:red;"> Body 标签 Style 属性 background-color:red ...

  10. Codeforces Round #417 (Div. 2)-A. Sagheer and Crossroad

    [题意概述] 在一个十字路口 ,给定红绿灯的情况, 按逆时针方向一次给出各个路口的左转,直行,右转,以及行人车道,判断汽车是否有可能撞到行人 [题目分析] 需要在逻辑上清晰,只需要把所有情况列出来即可 ...