什么是回调
函数调用可以分为三种模式,串行调用、异步调用、回调。这三种都是日常开发中常见到的方式。
一个方法执行完,再执行下一个,串行逻辑会阻塞线程执行流程,等到所有逻辑执行结束,线程才会结束。
异步执行是非阻塞类型。在主线程中,可以通过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();
});
}
}
参考
原文地址:https://www.jb51.cc/wenti/3280980.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。