文章目录

  • 1. 分类
  • 2. 案例
  • 1. 多线程中的回调
  • 2. Java 的回调案例


1. 分类

模块间的调用分三种:

  1. 同步调用,即阻塞式调用,A 调用 B 的时候,会一直等待 B 执行完成,然后再继续执行 A,适合 B 执行时间不长的情况;
  2. 异步调用,类似消息或事件的机制,A 通过另起一个线程去调用 B,之后 A 和 B 各自执行各自的,当 A 的执行需要 B 的执行结果时,需要使用一种方式来监听 B 的执行结果,Java 中使用 Callable+Future/FutureTask 的方式来实现这一需求,异步调用很好地解决了同步阻塞的问题;
  3. 回调,A 调用 B 后,B 主动调用 A 的过程,回调更像是一个约定,就是如果 A 调用了 B,那么 B 就必须要回调,而不需要显式去调用

2. 案例

1. 多线程中的回调

Java 多线程中可以通过 callable 和 future 或 futuretask 结合来获取线程执行后的返回值。实现方法是通过 get 方法来调用 callable 的 call 方法获取返回值

其实这种方法本质上不是回调,回调要求的是任务完成以后被调用者主动回调调用者的接口。而这里是调用者主动使用 get 方法阻塞获取返回值

案例:

public static void main(String[] args) throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newCachedThreadPool();
    Future<String> future = executor.submit(new Callable<String>() {
        @Override
        public String call() throws Exception {
            System.out.println("call");
            TimeUnit.SECONDS.sleep(1);
            return "str";
        }
    });
    //手动阻塞通过调用 get 来调用 call 方法获得返回值。
    System.out.println(future.get());
    //需要手动关闭,不然线程池的线程会继续执行。
    executor.shutdown();

    //使用futuretask同时作为线程执行单元和数据请求单元。
    FutureTask<Integer> futureTask = new FutureTask(new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            System.out.println("dasds");
            return new Random().nextInt();
        }
    });
    new Thread(futureTask).start(); // 作为线程执行单元
    //阻塞获取返回值
    System.out.println(futureTask.get());
}

2. Java 的回调案例

场景:
小明和小李相约一起去吃早饭,但是小李起的有点晚要先洗漱,等小李洗漱完成后,通知小明再一起去吃饭。小明就是类 A,小李就是类 B。不同的是我们新建一个吃饭的接口 EatRice,接口中有个抽象方法 eat()。在小明中调用这个接口,并实现 eat();小李声明这个接口对象,并且调用这个接口的抽象方法

代码:

interface EatRice {
    public void eat(String food);
}

//小明
class XiaoMing implements EatRice {

    //小明和小李一起吃饭
    public void eatFood() {
        XiaoLi xl = new XiaoLi();
        //A调用B的方法
        xl.washFace("大龙虾", this);//this指的是当前实例
    }

    @Override
    public void eat(String food) {

        System.out.println("小明和小李一起去吃" + food);
    }
}

//小李
class XiaoLi {

    public void washFace(String food, EatRice er) {
        System.out.println("小李要洗漱");
        //B回调了A的方法
        er.eat(food);
    }
}

//测试
class demo {
    public static void main(String args[]) {
        XiaoMing xm = new XiaoMing();
        xm.eatFood();
    }
}

结果:

Rxjava 主线程 回调 java多线程回调_Java