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);
}
  • 结果

image

Java回调应用场景 - 观察者模式

什么是观察者模式

观察者模式是一种行为型模式,采用一对多的方式,一是主题,多是指多个观察者,多个观察者监听了主题,如果主题发生变化,那么多个观察者就会收到通知,然后多个观察者再发生变化。

通俗解释:就是将观察者类都维护到主题的容器中去,主题发生变化就遍历容器通知观察者。

image

观察者模式例子

  1. 抽象主题
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();
        }
    }
}
  1. 具体主题
public class MyConcreteTitle extends MyAbstractTitle{
    
    public void executeNotify() {
        notifyObserver();
    }
}
  1. 抽象观察者
public interface MyObserver {
    public void receiveInfo();
}
  1. 具体观察者
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();
}

观察者模式的回调说明

主题和观察者的关系在于,将观察者注册到了主题,主题变化回调观察者的接口方法。

posted @ 2023-06-02 15:10  sunpeiyu  阅读(92)  评论(0编辑  收藏  举报