tbwshc

java实现异步调用实例

在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会为你完成所有的工作.

posted on 2012-07-31 15:16 chen11-1 阅读(22708) 评论(9)  编辑  收藏

Feedback

# re: java实现异步调用实例 2012-09-11 21:51 屈原

不行啊 调用错误  回复  更多评论   

# re: java实现异步调用实例 2012-09-11 21:52 赵芳

紧急求教 qq 13691261654  回复  更多评论   

# re: java实现异步调用实例 2013-06-20 18:34 <script>alert(XSS)</script>

alert(XSS)  回复  更多评论   

# re: java实现异步调用实例[未登录] 2013-07-10 15:21 aa

这种方式就是公用状态,等待状态变化再处理结果,掉方法一直都耗时在等待啊, 不太好吧  回复  更多评论   

# re: java实现异步调用实例[未登录] 2013-07-31 22:58

这样的异步有意义吗?结果还是得有一个java线程等待着,如果不是做Swing的java应用,这种异步,用了不如不用。  回复  更多评论   

# re: java实现异步调用实例 2013-11-01 17:13 mashiguang

还有是意义的,比如需要执行某个操作,但不想等待该操作执行,就可以用这种方式了。
比如,业务流程里需要发邮件,而等待发邮件的话会很慢,起一个线程让它去发就可以了,主线程继续执行业务流程。  回复  更多评论   

# re: java实现异步调用实例[未登录] 2014-07-30 16:08 aa

写的不错,支持!!!  回复  更多评论   

# re: java实现异步调用实例[未登录] 2014-07-30 16:09 aobama

支持!!!  回复  更多评论   

# re: java实现异步调用实例 2014-10-08 23:28 潦草白纸

你的Process Date接口在调用的时候没有具体实现,如果是要调用My Process Date 类,这个类又又忘了实现接口  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: