Java回调机制
什么是调用
同步调用
同步调用是最简单的方式,按照顺序,a调用b,当b执行完,那么a才会继续往下执行。如果b一直在执行,那么a将处于阻塞。这种情况适用于整个流程顺畅,不会出现执行时间过长的情况。不适于中间出现执行时间过长,导致整体性能下降,一部分代码长时间无法执行。
异步调用
异步调用就是为了避免出现同步调用阻塞的情况的。当a调用b,不管b执行多长时间,都会继续向下执行a的代码。当b执行完将通知a(a监听b的操作),做哪些操作就是回调。
Java中回调思路
a -> b -> a (callback)
流程解释:
① 首先A类中a方法调用B类中的b方法。
② 然后B类中的b方法执行完毕,再执行A类中的callback方法。
注意:
回调的关键是将自己的引用传递过去。可以看出回调的形式,是两个方法间的双向调用。而不使用回调,只是单方向调用。
Java中实现
例子:
快递员派送快递到客户手中,快递员通知客户快递送到丰巢了,然后客户领取快递后,确认了快递员派送成功。
- 快递货物类
/**
* 快递货物
*/
public class Goods {
/**
* 快递名称
*/
private String goodsName;
/**
* 快递状态
*/
private boolean goodsFlag;
public Goods(String goodsName, boolean goodsFlag) {
this.goodsName = goodsName;
this.goodsFlag = goodsFlag;
}
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public boolean isGoodsFlag() {
return goodsFlag;
}
public void setGoodsFlag(boolean goodsFlag) {
this.goodsFlag = goodsFlag;
}
}
- 客户确认回调接口
public interface ICallback {
// 确认收货
void confirm();
}
- 客户信息类
// 抽象客户
public interface ICustomer {
// 接收快递
void receive(ICallback callback);
}
// 具体客户
public class CustomerOne implements ICustomer{
@Override
public void receive(ICallback callback) {
// 确认收到货物
callback.confirm();
}
}
- 快递员类
public class Sender {
private Goods goods;
public Sender(Goods goods) {
this.goods = goods;
}
// 通知客户
public void inform(ICustomer customer) {
// 客户收到货物
customer.receive(new ICallback() {
@Override
public void confirm() {
goods.setGoodsFlag(true);
System.out.println("客户确认收到了货物!");
}
});
// 该笔运单结束
System.out.println("============== 该笔运单结束!");
}
}
- 测试
public static void main(String[] args) {
Goods goods = new Goods("生鲜类快递", false);
Sender sender = new Sender(goods);
ICustomer customer = new CustomerOne();
sender.inform(customer);
}
- 结果
Java回调应用场景 - 观察者模式
什么是观察者模式
观察者模式是一种行为型模式,采用一对多的方式,一是主题,多是指多个观察者,多个观察者监听了主题,如果主题发生变化,那么多个观察者就会收到通知,然后多个观察者再发生变化。
通俗解释:就是将观察者类都维护到主题的容器中去,主题发生变化就遍历容器通知观察者。
观察者模式例子
- 抽象主题
public abstract class MyAbstractTitle {
private List<MyObserver> list = new ArrayList<MyObserver>();
public void addObserver(MyObserver observer) {
list.add(observer);
}
public void delObserver(MyObserver observer) {
list.remove(observer);
}
public void notifyObserver() {
Iterator<MyObserver> its = list.iterator();
while (its.hasNext()) {
its.next().receiveInfo();
}
}
}
- 具体主题
public class MyConcreteTitle extends MyAbstractTitle{
public void executeNotify() {
notifyObserver();
}
}
- 抽象观察者
public interface MyObserver {
public void receiveInfo();
}
- 具体观察者
public class ObserverA implements MyObserver {
@Override
public void receiveInfo() {
System.out.println("观察者A收到通知!");
}
}
public class ObserverB implements MyObserver {
@Override
public void receiveInfo() {
System.out.println("观察者B收到通知!");
}
}
- 测试:
public static void main(String[] args) throws IOException {
MyConcreteTitle mct = new MyConcreteTitle();
MyObserver observerA = new ObserverA();
MyObserver observerB = new ObserverB();
mct.addObserver(observerA);
mct.addObserver(observerB);
mct.executeNotify();
}
观察者模式的回调说明
主题和观察者的关系在于,将观察者注册到了主题,主题变化回调观察者的接口方法。