任务接口
/**
* 一个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