Java-回调函数

Java-回调函数_第1张图片

什么是回调

函数调用可以分为三种模式,串行调用、异步调用、回调。这三种都是日常开发中常见到的方式。

一个方法执行完,再执行下一个,串行逻辑会阻塞线程执行流程,等到所有逻辑执行结束,线程才会结束。

异步执行是非阻塞类型。在主线程中,可以通过new Thread的方式异步执行逻辑,通过Thread执行的逻辑不会阻塞主流程。类似日志上报,发送kafka消息等,都可以通过异步的方式处理。

回调,就是客户程序A调用服务程序B中的一个函数F_B,然后B又在某个时候反过来调用A中的某个函数F_A,对于A来说,这个F_A便叫做回调函数。一般说来,A不会自己调用F_A,A提供F_A的目的就是让B来调用它。由于B并不知道A提供的F_A姓甚名谁,所以A会约定F_A的接口规范,然后由A提前通过B的一个函数R告诉B自己将要使用F_A函数,这个过程称为回调函数的注册,R称为注册函数。

下面举个通俗的例子: 某天,我打电话向你请教问题,当然是个难题,你一时想不出解决方法,于是我们约定:等你想出办法后打手机通知我 。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。

例子中加粗的两部分说明这是一个“异步+回调“的过程,异步便是我给你打完电话,没有等你相处结果,回调是你在想到办法之后通知我。这里我的手机号就相当提前在你这注册的回调函数,你处理完成之后,直接调用函数来通知我。

通过在工作中的场景,自认为回调和异步更搭配。另外就是写框架性的代码,回调用的会多一些。

java中回调的应用

可以想象一个场景,有数据库需要回填某些数据,数据回填之后要将数据修改数量,结束时间等进行记录。

这个场景是不是和例子比较像,都是主线程下发一个任务,子线程完成任务之后,通知主线程执行其他操作。可以看下代码

首先定义一个回调接口

//接口可以接收多个入参,有一个出餐
public interface FuncCallback<P, R> {
    R call(P... p);
}

然后定义数据处理类,这个类的入参除了数据处理中需要的参数外,还需要有回调类

public class DbDataFresh {
    /**
    * 数据处理执行逻辑,dataType,operator为业务逻辑需要的参数
    * FuncCallback callback 是绑定的回调接口。这样绑定之后,
    * 任意一个调用DbDataFresh.fresh的程序,都可以指定逻辑处理结束之后的回调
    * 在fresh方法中可以指定通过修改callback.call调用顺序,控制回调时机
    */
    public void fresh(Integer dataType, String operator, FuncCallback callback) {
        //do fresh, get data change count
        int total = 100;

        //callback call
        callback.call(total, System.currentTimeMillis());
    }
}

我们再看一下程序的主入口

public class UserHandleMain {
      private static final DbDataFresh dbDataFresh = new DbDataFresh();

      public static void main(String[] args) {
            //调用DbDataFresh.fresh方法,同时绑定回调
            //回调函数使用fresh方法传回来的数据进行其他逻辑处理
            dbDataFresh.fresh(1, "system", new FuncCallback() {
            @Override
            public Object call(Object[] p) {
                  if (p == null || p.length == 0) {
                        return "handle empty";
                  }
                  //遍历处理结果
                  StringBuilder res = new StringBuilder();
                  for (Object o : p) {
                        res.append(o.toString()).append("_");
                  }
                  System.out.println(res.toString());
                  return res.toString();
            }
            });

            //使用lambda方式,这种貌似是比较常见到的
            dbDataFresh.fresh(1, "system", p -> {
                  if (p == null || p.length == 0) {
                  return "handle empty";
                  }
                  //遍历处理结果
                  StringBuilder res = new StringBuilder();
                  for (Object o : p) {
                  res.append(o.toString()).append("_");
                  }
                  System.out.println(res.toString());
                  return res.toString();
            });
      }
}

参考

Java-接口回调-掘金
Java接口回调-csdn

你可能感兴趣的:(java,java,kafka,开发语言)