手写一个简单的异步回调框架

任务接口

/**
 * 一个worker,它需要有个方法,来代表这个worker将来做什么,
 * action就可以理解为一个耗时任务。action可以接收一个参数。
 */
public interface Worker {

    String action(Object object);
}

监听接口

/**
 * 这个listener用来做为回调,将worker的执行结果,放到result的参数里。
 */
public interface Listener {

    void result(Object result);
}

包装类

/**
 * 一个包装器Wrapper,来将worker和回调器包装一下
 */
public class Wrapper {

    private Object param;
    private Worker worker;
    private Listener listener;

    public Object getParam() {
        return param;
    }

    public void setParam(Object param) {
        this.param = param;
    }

    public Worker getWorker() {
        return worker;
    }

    public void setWorker(Worker worker) {
        this.worker = worker;
    }

    public Listener getListener() {
        return listener;
    }

    public void addListener(Listener listener) {
        this.listener = listener;
    }
}


测试类

/*
* @description: 模拟异步回调
* @return:
* @author: Ming
* @time: 2022/8/22
*/
public class Bootstrap {

    public static void main(String[] args) {
        Bootstrap bootstrap = new Bootstrap();
        Worker worker = bootstrap.newWorker();
        Wrapper wrapper = new Wrapper();
        wrapper.setWorker(worker);
        wrapper.setParam("hello");
        bootstrap.doWork(wrapper).addListener(new Listener() {
            @Override
            public void result(Object result) {
                System.out.println(Thread.currentThread().getName());
                System.out.println(result);
            }
        });
        System.out.println("主函数执行完毕:"+Thread.currentThread().getName());
    }


    private Wrapper doWork(Wrapper wrapper) {
        new Thread(() -> {
            Worker worker = wrapper.getWorker();
            String result = worker.action(wrapper.getParam());
            wrapper.getListener().result(result);
        }).start();
        return wrapper;
    }


    /**
     * 创建worker对象
     * @return
     */
    private Worker newWorker() {
        return new Worker() {
            @Override
            public String action(Object object) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return object + " world";
            }
        };
    }

}

执行结果和预料中的一样,并没有阻塞主函数
在这里插入图片描述
思考一下这段代码,会不会出现dowork执行比addListener快呢,这样就会导致dowork里的wrapper.getListener().result(result)出现空指针,因为dowork比addListener快,所以wrapper.getListenner()为null,所以报错啦

bootstrap.doWork(wrapper).addListener(new Listener() {
            @Override
            public void result(Object result) {
                System.out.println(Thread.currentThread().getName());
                System.out.println(result);
            }
        });

试一下把dowork方法中的阻塞注释掉再执行,就报错了

在这里插入图片描述
若先addListener(),再dowork估计就不会,把main函数改一下

 public static void main(String[] args) {
        Bootstrap bootstrap = new Bootstrap();
        Worker worker = bootstrap.newWorker();
        Wrapper wrapper = new Wrapper();
        wrapper.setWorker(worker);
        wrapper.setParam("hello");
        //先监听
        wrapper.addListener(new Listener() {
            @Override
            public void result(Object result) {
                System.out.println(Thread.currentThread().getName());
                System.out.println(result);
            }
        });
        //后执行
        bootstrap.doWork(wrapper);
        System.out.println("主函数执行完毕:"+Thread.currentThread().getName());
    }

没有报错了,666

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值