zoukankan      html  css  js  c++  java
  • java异步操作实例

    1.异步操作过程实例:

    A.开启一个线程一直执行耗时操作

    B.通过每隔多长多件轮询线程是否实行完毕,thread.isCompleted()

    C.执行完毕后,通过回调函数返回真实信息

    一个调用者在调用耗时操作,不能立即返回数据时,先返回一个取货凭证.然后在过一断时间后
    凭取货凭证来获取真正的数据.
     
    所以连结调用者和真实数据之间的桥梁是取货凭证.我们先来看它的实现:
     
    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会为你完成所有的工作.

  • 相关阅读:
    HTB-靶机-Charon
    第一篇Active Directory疑难解答概述(1)
    Outlook Web App 客户端超时设置
    【Troubleshooting Case】Exchange Server 组件状态应用排错?
    【Troubleshooting Case】Unable to delete Exchange database?
    Exchange Server 2007的即将生命周期,您的计划是?
    "the hypervisor is not running" 故障
    Exchange 2016 体系结构
    USB PE
    10 months then free? 10个月,然后自由
  • 原文地址:https://www.cnblogs.com/panxuejun/p/5957244.html
Copyright © 2011-2022 走看看