使用guava實現(xiàn)異步回調(diào)的簡單demo

使用guava實現(xiàn)異步回調(diào)

guava介紹

guava
是google針對java異步調(diào)用任務(wù)的加強框架,它與Java的FutureTask的區(qū)別如下

  • 1.FutureTask是主動調(diào)用的模式,“調(diào)用線程”會主動獲取異步結(jié)果,在獲取得到結(jié)果之前一直都保持這阻塞的狀態(tài),并且會一直阻塞,直到拿到異步調(diào)用的結(jié)果。
  • 2.Guava是異步回調(diào)模式,“調(diào)用線程”不會主動獲取異步結(jié)果,而是通過被調(diào)用線程執(zhí)行回調(diào)鉤子函數(shù),“調(diào)用線程”在執(zhí)行完自己的邏輯之后就結(jié)束了,當(dāng)回調(diào)函數(shù)執(zhí)行時,可能“調(diào)用函數(shù)”已經(jīng)停止很久了

FutureTask的異步調(diào)用模式簡單demo代碼

public class javaFutureDemo {

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

    static class BoilWaterThread implements Callable<Boolean> {

        @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<Boolean> {
        @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<Boolean> bJob = new BoilWaterThread();
        FutureTask<Boolean> bTask = new FutureTask<>(bJob);
        Thread bThread = new Thread(bTask,"燒水線程");

        Callable<Boolean> cJob = new CleanCupThread();
        FutureTask<Boolean> 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異步回調(diào)流程

異步回調(diào)流程

  • 1.實現(xiàn)Java的Callable接口,創(chuàng)建異步執(zhí)行邏輯,如果是不需要返回值,那么也可以實現(xiàn)Runnable接口
  • 2.創(chuàng)建Guava線程池
  • 3.將(1)中創(chuàng)建的Callable/Runnable異步執(zhí)行的邏輯的實例提交到guava線程池,從而獲得listenableFuture異步任務(wù)實例
  • 4.創(chuàng)建FutureCallable回調(diào)實例,通過Futures.addCallableback將回調(diào)實例綁定到ListenableFuture異步任務(wù)上。

guava異步回調(diào)實現(xiàn)demo

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

    static class BoilWaterThread implements Callable<Boolean> {
        @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<Boolean> {
        @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();

        //燒水的業(yè)務(wù)邏輯
        Callable<Boolean> bJob = new BoilWaterThread();
        //洗杯子的業(yè)務(wù)邏輯
        Callable<Boolean> cJob = new CleanThread();

        //創(chuàng)建java線程池
        ExecutorService jPool = Executors.newFixedThreadPool(10);

        //構(gòu)造guava線程
        ListeningExecutorService gPool = MoreExecutors.listeningDecorator(jPool);

        //燒水的回調(diào)鉤子
        FutureCallback<Boolean> hotWaterHook = new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if(aBoolean){
                    drinkJob.waterOK = true;
                    //執(zhí)行回調(diào)方法
                    drinkJob.drinkTea();
                }
            }

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

        //啟動燒水線程
        ListenableFuture<Boolean> hotFuture = gPool.submit(bJob);

        //設(shè)置燒水任務(wù)的回調(diào)鉤子
        Futures.addCallback(hotFuture,hotWaterHook);

        //啟動清洗線程
        ListenableFuture<Boolean> washFuture = gPool.submit(cJob);

        //使用匿名實例,作為清洗之后的回調(diào)函數(shù)
        Futures.addCallback(washFuture, new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if(aBoolean){
                    drinkJob.cupOK = true;
                    //執(zhí)行回調(diào)方法
                    drinkJob.drinkTea();
                }
            }

            @Override
            public void onFailure(Throwable throwable) {
                System.out.println("杯子洗不了,沒有茶喝了");
            }
        });
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容