Java 回调机制解析(同步回调/异步回调)

回调:简单来说,就是我调用你的函数,你调用我的函数。正规一点的说法就是类A的a()函数调用类B的b()函数,当类B的b()函数的执行时又去调用类A里的函数。是一种双向的调用方式。一般情况下,回调分两种,分别是同步回调异步回调

  • 同步回调:一种双向调用模式,被调用方在函数被调用时也会调用对方的函数。下面用一个计算器的例子来展示(为了方便,写在一个文件里)。
public class CallBack
{
     public static void main(String []args)
     {
        int a = 10452;
        int b = 423;
        //实例化计算器Calculator类
        Calculator calculator = new Calculator(a,b);
        //调用计算器calculator的计算函数
        calculator.calculation();
        //控制台输出
        System.out.println("/========================/");
     }
}

//回调接口
interface CallBackInterface
{
    //计算的结果回调函数
     public void calculationResult(int a, int b, int result);
}

//计算的具体逻辑类
class Logic
{
    //计算的具体逻辑(计算方式)
    public void calculationLogic(int a, int b, CallBackInterface callBackInterface)
    {
        int result = a + b;
        //利用传进来的对象,回调计算结果.
        callBackInterface.calculationResult(a, b, result);
    }
}

//计算器类,实现了回调接口,用于本类的实例化对象传值
class Calculator implements CallBackInterface
{
    private int a,b;

    public Calculator(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public void calculation()
    {
        /*匿名实例化计算的具体逻辑类Logic,并调用计算函数.
        this是本类对象,因为实现了回调接口CallBackInterface,所以可以传值.*/
        new Logic().calculationLogic(a, b, this);
    }

    //因为实现了回调接口CallBackInterface,必须要重写计算的结果回调函数calculationResult
    public void calculationResult(int a, int b, int result)
    {
        //控制台输出
        System.out.println(a + " + " + b + " = " + result);
    }
}

运行结果:
10452 + 423 = 10875
/========================/


  • 异步回调:一种类似消息或事件的机制,被调用方在函数在收到某种讯息或发生某种事件时,才去调用对方的函数,即通过异步消息进行通知。简单来说,类A的a()函数调用类B的b()函数,但是b()函数很耗时,不确定什么时候执行完毕,如果是同步调用的话会等b()执行完成后才往下执行回调类A中的函数,如果是异步回调的话调用了b()函数,虽然b()函数没有执行完,但仍然继续往下执行,为了完成这点,就需要另开一个线程了。下面还是用一个计算器的例子来展示(为了方便,写在一个文件里)。
public class CallBack
{
     public static void main(String []args)
     {
        int a = 10452;
        int b = 423;
        //实例化计算器Calculator类
        Calculator calculator = new Calculator(a,b);
        //调用计算器calculator的计算函数
        calculator.calculation();
        //控制台输出
        System.out.println("/========================/");
     }
}

//回调接口
interface CallBackInterface
{
    //计算的结果回调函数
     public void calculationResult(int a, int b, int result);
}

//计算的具体逻辑类
class Logic
{
    //计算的具体逻辑(计算方式)
    public void calculationLogic(int a, int b, CallBackInterface callBackInterface)
    {
        int result = a + b;
        //让线程等待5秒
        try
        { 
            Thread.sleep(5 * 1000); 
        } catch (InterruptedException e)
        { 
            e.printStackTrace(); 
        } 
        //利用传进来的对象,回调计算结果.
        callBackInterface.calculationResult(a, b, result);
    }
}

//计算器类,实现了回调接口,用于本类的实例化对象传值
class Calculator implements CallBackInterface
{
    private int a,b;

    public Calculator(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public void calculation()
    {
        //开启另一个子线程
        new Thread(new Runnable()
        { 
            public void run()
            { 
                /*匿名实例化计算的具体逻辑类Logic,并调用计算函数.
                this是本类对象,因为实现了回调接口CallBackInterface,所以可以传值.*/
                new Logic().calculationLogic(a, b, Calculator.this);
            } 
        }).start(); 
    }

    //因为实现了回调接口CallBackInterface,必须要重写计算的结果回调函数calculationResult
    public void calculationResult(int a, int b, int result)
    {
        //控制台输出
        System.out.println(a + " + " + b + " = " + result);
    }
}

运行结果:
/========================/
10452 + 423 = 10875

你会发现,输出”/====/”明明是放在代码的最后执行的,结果却先执行输出了,这是因为开了另一个线程,而异步回调和同步回调最大的不同就是异步回调里新建了一个子线程。异步回调常见于请求服务器数据,当取到数据时,会进行回调。


扩展知识:另一种回调(同步),主要是为解决当实现的逻辑不明确时的问题。还是用计算器的例子,比如不一定用计算器进行加法运算,也有可能进行乘法运算(为了方便,写在一个文件里)。

public class CallBack
{
     public static void main(String []args)
     {
        int aa = 10452;
        int bb = 423;
        //实例化计算器Calculator类,并传一个Logic对象
        Calculator calculator = new Calculator(new Logic()
        {
            //重写计算逻辑函数calculationLogic,实现具体计算逻辑
            public void calculationLogic(int a, int b){
                int result = a * b;
                System.out.println(a + " * " + b + " = " + result);
            }
        });
        //调用计算器calculator的计算函数calculation
        calculator.calculation(aa, bb);
        //控制台输出
        System.out.println("/========================/");
     }
}

//计算的逻辑回调接口
interface Logic
{
    //计算的逻辑回调函数
     public void calculationLogic(int a, int b);
}

//计算器类
class Calculator
{
    private Logic logic;

    public Calculator(Logic logic)
    {
        this.logic = logic;
    }

    public void calculation(int aa, int bb)
    {
        //调用logic对象里的计算逻辑函数calculationLogic
        logic.calculationLogic(aa, bb);
    }
}

运行结果:
10452 * 423 = 4421196
/========================/

异步回调也同理,在Calculator类的calculation()函数里新建一个线程就行了,这里就不举例了。

你可能感兴趣的:(Java)