Java多线程实现异步调用


当调用者调用耗时操作时,无需一直等待,先得到提货单,过段时间通过提货单获取真实数据

实现异步调用的角色有如下三个角色:调用者、接收者、提货单、真实数据
为了能够更好的理解,现有一个场景:

去蛋糕店买蛋糕,不需要等蛋糕做出来(假设现做要很长时间),只需要领个提货单就可以了(去干别的事情),等到蛋糕做好了,再拿提货单取蛋糕就可以了。

/**
 * 模拟客户(d1、d2、d3)订蛋糕请求,返回得到FutureData(提货单)
 * 之后,客户不用一直等待蛋糕(RealData)忙自己该忙的事
 * 做完其它事情后再取蛋糕
 */
public class Caller {

    public static void main(String[] args){
        Receiver receiver = new Receiver();
        Data d1 = receiver.request();//订蛋糕请求
        Data d2 = receiver.request();
        Data d3 = receiver.request();
        
        try {
            Thread.sleep(3000); //模拟客户做其它事情
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
                
        System.out.println(d1.getContent());//取蛋糕(RealData)
        System.out.println(d2.getContent());
        System.out.println(d3.getContent());
    }
}


/**
 * Receiver 接受者:相当于场景中的当蛋糕店,接收到客户(Caller)订单request,
 *                  服务员首先开订单证明(提货单:FutureData)给客户,客户过段时间再来取蛋糕(RealData)
 *                  开启线程make RealData
 */
public class Receiver {

    public Data request(){
        final FutureData future = new FutureData();
        new Thread(){
            public void run(){
                RealData realdata = new RealData();
                future.setRealData(realdata);
            }    
        }.start();
        return future;
    }
}


/**
 * FutureData:提货单
 * 蛋糕做完调用setRealData
 * 客户getContent获取蛋糕,如果蛋糕没有做好,继续等待,直到蛋糕做好
 */
public class FutureData implements Data {
    private RealData realdata = null;
    private boolean ready = false;
    
    public synchronized String getContent() {
        while(!ready){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return realdata.getContent();
    }
    public synchronized void setRealData(RealData realdata) {
        this.realdata = realdata;
        this.ready = true;
        notifyAll();    
    }
}


public class RealData implements Data {

    private String content;    
    /**
     * 睡眠5秒模仿做蛋糕
     */
    public RealData(){
        System.out.println("begin making RealData");
        try {
            System.out.println("RealData processing");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("RealData maked");
        this.content="真材实料";
    }
    
    public String getContent() {
        return content;
    }
}


每个线程只是专门负责制作特定顾客所需要的“蛋糕”。也就是顾客A对应着蛋糕师傅A,顾客B对应着蛋糕师傅B。即使顾客B的蛋糕被先做好了,顾客A也只能等待蛋糕师傅A把蛋糕做好。换句话说,顾客之间没有竞争关系。

  类FutureData的两个方法被设置为synchronized,实际上蛋糕师傅A与顾客A之间的互斥关系,也就是顾客A必须等待蛋糕师傅A把蛋糕做好后,才能拿走,而与蛋糕师傅B是否做好了蛋糕没有关系。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值