`
wind_bell
  • 浏览: 291329 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

多线程编程 高级主题(一)注:转

阅读更多

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;
 }
}
 
为了简单化说明(不把它们的关系开得复杂),这里用Object代替了真实数据.而真实的实现中
我们应该把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();

分享到:
评论

相关推荐

    CSharp注:高级开发人员路线图

    这份“CSharp注:高级开发人员路线图”旨在为有经验的C#开发者提供一个提升技能和知识的指导路径。以下是一些关键的学习领域和知识点: 1. **语言特性**: - **泛型**:理解如何使用泛型类、接口和方法,以及它们...

    学软件编程需必学的英语)第二学年Java方向

    5. **Batch批**:一次处理多个操作的批量操作。 6. **Fetch取**:类似于“Load”,但更侧重于关联对象的加载策略。 **第五章**:探讨了关于查询构建和优化的主题。 1. **Criteria标准**:基于特定条件构造查询的一...

    how2j离线免费版.rar

    【标签】"java"表示该资源包主要围绕Java编程语言展开,涵盖了Java的基础知识、语法特性以及高级主题。"springboot"则说明了教程也包含了SpringBoot框架的使用,SpringBoot是Java生态中广泛使用的微服务开发框架,...

    JAVA初级35选7彩票代码

    在Java编程语言中,开发一个35选7的彩票系统是一项常见的练习,旨在帮助初学者理解和运用基础的编程概念。35选7彩票意味着玩家从35个...这个简单的项目是学习和实践Java编程的好起点,同时也能逐步深入到更多高级主题。

    专业软件、书籍下载地址 很好的

    - **内容简介**:本书介绍了C++中的多线程编程方法,帮助读者理解并实现高效的并发程序。 - **下载地址**:[http://bbs.topsage.com/dispbbs.asp?boardID=121&ID=181038]...

    Android开发从入门到精通源码

    1. **多线程与异步处理**:讲解如何使用Thread、AsyncTask、Handler、Runnable等实现多线程操作,提升应用的性能和用户体验。 2. **网络编程**:介绍Android中的网络请求,如使用HttpURLConnection、OkHttp库,以及...

    Linux程序设计 第4版.haozip01

    12.8 多线程 438 12.9 小结 442 第13章 进程间通信:管道 443 13.1 什么是管道 443 13.2 进程管道 444 13.3 将输出送往popen 445 13.3.1 传递更多的数据 446 13.3.2 如何实现popen 447 13.4 pipe调用 449 ...

    Linux程序设计 第4版.haozip02

    12.8 多线程 438 12.9 小结 442 第13章 进程间通信:管道 443 13.1 什么是管道 443 13.2 进程管道 444 13.3 将输出送往popen 445 13.3.1 传递更多的数据 446 13.3.2 如何实现popen 447 13.4 pipe调用 449 ...

Global site tag (gtag.js) - Google Analytics