Java 回调机制实例(同步&异步式)

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

Java 回调机制

接口回调是一种常见的设计模型,通常模块之间都有一定的调用关系,例如模块A 需要模块B 提供的某个服务,服务完成后将结果告诉模块A, 这时候模块 A 就需要告诉模块 B 一个联系方式,使 B 完成时来通知自己,这个场景就可以使用回调, 而这个联系方式就是回调接口Callback 。

同步式

假定有这样一个场景:有两个模块分别为主模块和Mysql 模块,主模块中间一个环节需要根据area 查询所有person, Mysql 模块提供这样的服务,于是主模块就需要调用Mysql 模块的服务,服务完成后将结果告诉主模块:

定义回调接口 CallBack

public interface CallBack
{
    void success(List<String> persons);
}

主模块代码:

public class Main
{
    public static void main(String[] args)
    {
        MysqlService.selectPersonsByArea("beijing" , new CallBack()
        {
            @Override
            public void success(List<String> persons)
            {
                System.out.println("收到回调结果:"+String.join(",", persons));
            }
        });
        System.out.println("主模块运行完成!!!");
    }
}

Mysql 模块代码:

public class MysqlService
{
    public static void selectPersonsByArea(String area, CallBack callBack)
    {
        // 模拟查询操作1s 阻塞
        Thread.sleep(1000);
        // 查询出属于本area 的persons
        List<String> persons= Arrays.asList("lilei", "wangmiao", "heyue");
        callBack.success(persons);
    }
}

运行结果:

阻塞大概1s 后输出结果如下:

收到回调结果:lilei,wangmiao,heyue
主模块运行完成!!!

异步式

从上面的运行结果,我们可以知道,主模块会先运行完Mysql 模块的查询,才能执行下面的代码逻辑,即主模块阻塞在了Mysql 模块的查询,要是因为网络、Mysql 模块性能等问题,主模块的麻烦就大了…

所以我们需要将这块变为异步回调,Mysql 查询服务并不阻塞主模块,更改后如下:

public class MysqlService
{
    private static final ThreadPoolExecutor pools = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<Runnable>(5));

    public static void selectPersonsByArea(String area, CallBack callBack)
    {
        pools.execute(() ->
        {
            // 查询出属于本area 的persons
            try
            {
                // 模拟查询阻塞1s
                Thread.sleep(1000);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            List<String> persons= Arrays.asList("lilei", "wangmiao", "heyue");
            callBack.success(persons);
        });
    }
}

运行结果如下:

主模块首先输出:主模块运行完成!!!

然后阻塞1s 后输出: 收到回调结果:lilei,wangmiao,heyue

主模块运行完成!!!
收到回调结果:lilei,wangmiao,heyue

参考内容

猜你喜欢

转载自blog.csdn.net/qq_24871519/article/details/84489587