Java——回调机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lzx_2011/article/details/72853825

调用方式

  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上去监听点击事件,在点击时被调用,这就是一个异步回调。

总结

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

猜你喜欢

转载自blog.csdn.net/lzx_2011/article/details/72853825