Java回调函数

Java回调函数

1.前言

先让我们通过一个生活中的场景来还原一下回调的场景:你遇到了一个技术难题(比如,1+1等于几?,于是你去咨询大牛,大牛说现在正在忙,待会儿告诉你结果

此时,你可能会去刷朋友圈了,等大牛忙完之后,告诉你答案是2

那么,这个过程中询问问题(调用对方接口),然后问题解决之后再告诉你(对方处理完再调用你,通知结果),这一过程便是回调

2.系统调用的分类

应用系统模块之间的调用,通常分为:同步调用,异步调用,回调。

img

同步调用是最基本的调用方式。类A的a()方法调用类B的b()方法,类A的方法需要等到B类的方法执行完成才会继续执行。如果B的方法长时间阻塞,就会导致A类方法无法正常执行下去

img

如果A调用B,B的执行时间比较长,那么就需要考虑进行异步处理,使得B的执行不影响A。通常在A中新起一个线程用来调用B,然后A中的代码继续执行

异步通常分两种情况:第一,不需要调用结果,直接调用即可,比如发送消息通知;第二,需要异步调用结果,在Java中可使用Future+Callable实现
img

通过上图我们可以看到回到属于一种双向的调用方式。回调的基本上思路是:A调用B,B处理完之后再调用A提供的回调方法(通常为callback())通知结果

通常回调分为:同步回调和异步回调。网络上大多数的回调案例都是同步回调

其中同步回调与同步调用类似,代码运行到某一个位置的时候,如果遇到了需要回调的代码,会在这里等待,等待回调结果返回后再继续执行

而异步回调与异步调用类似,代码执行到需要回调的代码的时候,并不会停下来,而是继续执行,当然可能过一会回调的结果会返回回来

3.伪代码实现
1.定义CallBack接口

将回调的功能进行单独抽离

public interface CallBack { 
    void callback(String string); 
} 
2.定义问问题的人Person
public class Person implements CallBack { 
 
    private Genius genius; 
 
    public Person(Genius genius) { 
        this.genius = genius; 
    } 
 
    @Override 
    public void callback(String string) { 
        System.out.println("收到答案:" + string); 
    } 
 
    public void ask() { 
        genius.answer(this); 
    } 
 
} 
3.定义回答问题的人Genius
public class Genius { 
 
    public void answer(CallBack callBack) { 
        System.out.println("在忙其他事..."); 
        try { 
            Thread.sleep(2000); 
            System.out.println("忙完其他事,开始计算..."); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 
 
        System.out.println("天才计算出答案为:2"); 
        // 回调告诉你 
        callBack.callback("2"); 
    } 
} 
4.测试
public static void main(String[] args) { 
    Genius genius = new Genius(); 
    Person you = new Person(genius); 
    you.ask(); 
} 

上面的实例演示了同步回调,很明显在调用的过受到Genius执行时长的影响,需要等到Genius处理完才能继续执行Person方法中的后续代码

下面在上述示例上进行改进,Person提供一个支持异步回调的方法:

 public void askASyn() { 
    System.out.println("创建新线程请教问题"); 
    new Thread(() -> genius.answer(this)).start(); 
    System.out.println("新线程已启动..."); 
} 

在该方法内,新建了一个线程用来处理Genius#answer方法的调用,这样就能够跳过Genius#answer方法的阻塞,直接执行下面的操作(日志打印)

posted @   zhangyf1121  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示