使用guava实现异步回调的简单demo

使用guava实现异步回调

guava介绍

guava
是google针对java异步调用任务的加强框架,它与Java的FutureTask的区别如下

  • 1.FutureTask是主动调用的模式,“调用线程”会主动获取异步结果,在获取得到结果之前一直都保持这阻塞的状态,并且会一直阻塞,直到拿到异步调用的结果。
  • 2.Guava是异步回调模式,“调用线程”不会主动获取异步结果,而是通过被调用线程执行回调钩子函数,“调用线程”在执行完自己的逻辑之后就结束了,当回调函数执行时,可能“调用函数”已经停止很久了

FutureTask的异步调用模式简单demo代码

public class javaFutureDemo {

    public static final int SLEEP_GAP = 500;
    public static String getCurThreadName(){
        return Thread.currentThread().getName();
    }

    static class BoilWaterThread implements Callable {

        @Override
        public Boolean call() {
            try {
                System.out.println("清洗水瓶");
                System.out.println("灌上凉水");
                System.out.println("烧开水");
                Thread.sleep(SLEEP_GAP);
                System.out.println("水开了");
                return true;
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
    }
    static class CleanCupThread implements Callable {
        @Override
        public Boolean call() {
            try{
                System.out.println("洗杯子");
                System.out.println("洗茶具");
                Thread.sleep(SLEEP_GAP);
                System.out.println("洗好了");
                return true;
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
    }

    public static void drinkTea(Boolean waterOk,Boolean cupOk){
        if(waterOk && cupOk){
            System.out.println("泡茶喝");
        }else if(!waterOk){
            System.out.println("水没烧开,泡不了茶");
        }else if(!cupOk){
            System.out.println("杯子没有洗好,泡不了茶");
        }
    }

    public static void main(String[] args) {
        Callable bJob = new BoilWaterThread();
        FutureTask bTask = new FutureTask<>(bJob);
        Thread bThread = new Thread(bTask,"烧水线程");

        Callable cJob = new CleanCupThread();
        FutureTask cTask = new FutureTask<>(cJob);
        Thread cThread = new Thread(cTask,"清洗杯子线程");

        bThread.start();
        cThread.start();

        try{
            Boolean waterOk = bTask.get();
            Boolean cupOk = cTask.get();
            drinkTea(waterOk,cupOk);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("泡好茶了");
    }
}

guava异步回调流程

异步回调流程

  • 1.实现Java的Callable接口,创建异步执行逻辑,如果是不需要返回值,那么也可以实现Runnable接口
  • 2.创建Guava线程池
  • 3.将(1)中创建的Callable/Runnable异步执行的逻辑的实例提交到guava线程池,从而获得listenableFuture异步任务实例
  • 4.创建FutureCallable回调实例,通过Futures.addCallableback将回调实例绑定到ListenableFuture异步任务上。

guava异步回调实现demo

public class GuavaFutureDemo {
    public static final int SLEEP_GAP = 3000;

    static class BoilWaterThread implements Callable {
        @Override
        public Boolean call() {
            try {
                System.out.println("清洗水瓶");
                System.out.println("灌上凉水");
                System.out.println("烧开水");
                Thread.sleep(SLEEP_GAP-1000);
                System.out.println("水开了");
                return true;
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
    }

    static class CleanThread implements Callable {
        @Override
        public Boolean call() {
            try {
                System.out.println("清洗水瓶");
                System.out.println("清茶具");
                Thread.sleep(SLEEP_GAP);
                System.out.println("洗好了");
                return true;
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
    }

    static class DrinkJob{
        boolean waterOK = false;
        boolean cupOK = false;

        public void drinkTea(){
            if(waterOK && cupOK){
                System.out.println("泡茶喝,茶喝完");
//                this.waterOK = false;
            }
        }
    }

    public static void main(String[] args) {
        Thread.currentThread().setName("泡茶喝线程");
        //新起一个线程,作为泡茶主线程
        DrinkJob drinkJob = new DrinkJob();

        //烧水的业务逻辑
        Callable bJob = new BoilWaterThread();
        //洗杯子的业务逻辑
        Callable cJob = new CleanThread();

        //创建java线程池
        ExecutorService jPool = Executors.newFixedThreadPool(10);

        //构造guava线程
        ListeningExecutorService gPool = MoreExecutors.listeningDecorator(jPool);

        //烧水的回调钩子
        FutureCallback hotWaterHook = new FutureCallback() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if(aBoolean){
                    drinkJob.waterOK = true;
                    //执行回调方法
                    drinkJob.drinkTea();
                }
            }

            @Override
            public void onFailure(Throwable throwable) {
                System.out.println("烧水失败了,没有茶喝了");
            }
        };

        //启动烧水线程
        ListenableFuture hotFuture = gPool.submit(bJob);

        //设置烧水任务的回调钩子
        Futures.addCallback(hotFuture,hotWaterHook);

        //启动清洗线程
        ListenableFuture washFuture = gPool.submit(cJob);

        //使用匿名实例,作为清洗之后的回调函数
        Futures.addCallback(washFuture, new FutureCallback() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if(aBoolean){
                    drinkJob.cupOK = true;
                    //执行回调方法
                    drinkJob.drinkTea();
                }
            }

            @Override
            public void onFailure(Throwable throwable) {
                System.out.println("杯子洗不了,没有茶喝了");
            }
        });
    }
}

你可能感兴趣的:(使用guava实现异步回调的简单demo)