Java——回调机制

来源:互联网 发布:ubuntu 阿里源 gpg 编辑:程序博客网 时间:2024/06/07 05:15

调用方式

  1. 同步调用:类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕,a()方法继续往下走。这种调用方式适用于方法b()执行时间不长的情况,因为b()方法执行时间一长或者直接阻塞的话,a()方法的余下代码是无法执行下去的,这样会造成整个流程的阻塞。

  2. 异步调用:类A的方法方法a()通过新起线程的方式调用类B的方法b(),代码接着直接往下执行。

  3. 回调:包括同步回调和异步回调。

    • 类A的a()方法调用类B的b()方法
    • 类B的b()方法执行完毕主动调用类A的callback()方法

经典回调方式

Class A实现接口CallBack callback——背景1

class A中包含一个class B的引用b ——背景2

class B有一个参数为callback的方法f(CallBack callback) ——背景3

A的对象a调用B的方法 f(CallBack callback) ——A类调用B类的某个方法 C

然后b就可以在f(CallBack callback)方法中调用A的方法 ——B类调用A类的某个方法D

一个经典例子让你彻彻底底理解java回调机制

示例

以工人向老板请假为例:

  • 同步回调:工人打电话向老板请假,在电话中一直等待老板回复,老板同意后,再答谢老板。

  • 异步回调:工人打电话向老板请假,老板在开会等会给答复,然后工人挂掉电话干别的事情并等待老板的通知,老板回电话同意请假,工人答谢老板。

结构设计

Callback 接口中有 replyWorker() 答复工人请假请求接口,也是老板决定后需要回调的方法。

Worker 类实现回调接口,并持有 Boss 的引用,向 Boss 注册监听器,等待 Boss 的回复。

Boss 类回调 Worker 的方法来答复 Worker 的请假。

代码实现

Callback 接口

interface Callback {    /**     * 答复工人请假请求     */    void replyWorker(String message);}

Worker 类实现回调接口,并持有 Boss 的引用,向 Boss 注册监听器,等待 Boss 的回复

class Worker implements Callback {    private Boss boss;    public Worker(Boss boss){        this.boss = boss;    }    public void leave(){        System.out.println("请求批准请假两天");        //同步回调 (可以分别注释掉同步和异步回调的代码,看运行效果)        boss.reply(this);  //工人注册监听方法        System.out.println("同步阻塞等待老板的答复后,才能做别的事情");        //异步回调        new Thread(new Runnable() {            @Override            public void run() {                boss.reply(Worker.this);            }        }).start();        System.out.println("异步非阻塞,做别的事情并等待老板的回复");    }    @Override    public void replyWorker(String message){        System.out.println("老板回复: " + message);    }}

Boss 类回调 Worker 的方法来答复 Worker 的请假

class Boss {    public void reply(Callback callback){        try {            //老板思考2s 后回复            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        callback.replyWorker("同意请假");    }}

测试代码

public class CallbackPattern {    public static void main(String[] args){        Boss boss = new Boss();        Worker worker = new Worker(boss);        worker.leave();    }}

完整代码见 https://github.com/lzx2011/java-scaffold

同步回调运行结果

请求批准请假两天老板回复: 同意请假同步阻塞等待老板的答复后,才能做别的事情

异步回调运行结果

请求批准请假两天异步非阻塞,做别的事情并等待老板的回复老板回复: 同意请假

应用

回调是一种机制,很多语言里都有不同的实现,观察者模式也是回调的一种具体实现。观察者模式可以见我的 观察者模式 文章。回调机制的应用也很广泛,例如说java.util.Collections.sort(List, Comparator),这个sort()方法就定义了一个流程实现排序,而具体的顺序则由传入的Comparator参数来确定——这就是一个同步回调。又例如说GUI编程中,一个按钮被点击之后要做点事情,大家可以注册个ActionListener上去监听点击事件,在点击时被调用,这就是一个异步回调。

总结

回调的核心就是回调方将自身的引用传递给调用方,这样调用方就可以在调用完毕之后告诉回调方它想要知道的信息。本文主要是我的思考和总结。

原创粉丝点击