中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Java基礎(chǔ)9:解讀Java回調(diào)機(jī)制

更多內(nèi)容請關(guān)注微信公眾號【Java技術(shù)江湖】

景泰網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)于2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

這是一位阿里 Java 工程師的技術(shù)小站,作者黃小斜,專注 Java 相關(guān)技術(shù):SSM、SpringBoot、MySQL、分布式、中間件、集群、Linux、網(wǎng)絡(luò)、多線程,偶爾講點(diǎn)Docker、ELK,同時(shí)也分享技術(shù)干貨和學(xué)習(xí)經(jīng)驗(yàn),致力于Java全棧開發(fā)?。P(guān)注公眾號后回復(fù)”資料“即可領(lǐng)取 3T 免費(fèi)技術(shù)學(xué)習(xí)資源以及我我原創(chuàng)的程序員校招指南、Java學(xué)習(xí)指南等資源)

Java基礎(chǔ)9:解讀Java回調(diào)機(jī)制cdn.xitu.io/2019/4/6/169f1735fd0d1d16?w=900&h=500&f=jpeg&s=109856">

本文主要介紹了Java中的回調(diào)機(jī)制,以及Java多線程中類似回調(diào)的機(jī)制。

具體代碼在我的GitHub中可以找到

https://github.com/h3pl/MyTech

文章首發(fā)于我的個(gè)人博客:

https://h3pl.github.io/2018/04/26/javase9

更多關(guān)于Java后端學(xué)習(xí)的內(nèi)容請到我的CSDN博客上查看: https://blog.csdn.net/a724888

模塊間的調(diào)用

本部分摘自https://www.cnblogs.com/xrq730/p/6424471.html

在一個(gè)應(yīng)用系統(tǒng)中,無論使用何種語言開發(fā),必然存在模塊之間的調(diào)用,調(diào)用的方式分為幾種:

(1)同步調(diào)用

同步調(diào)用是最基本并且最簡單的一種調(diào)用方式,類A的方法a()調(diào)用類B的方法b(),一直等待b()方法執(zhí)行完畢,a()方法繼續(xù)往下走。這種調(diào)用方式適用于方法b()執(zhí)行時(shí)間不長的情況,因?yàn)閎()方法執(zhí)行時(shí)間一長或者直接阻塞的話,a()方法的余下代碼是無法執(zhí)行下去的,這樣會造成整個(gè)流程的阻塞。

Java基礎(chǔ)9:解讀Java回調(diào)機(jī)制

(2)異步調(diào)用

Java基礎(chǔ)9:解讀Java回調(diào)機(jī)制

異步調(diào)用是為了解決同步調(diào)用可能出現(xiàn)阻塞,導(dǎo)致整個(gè)流程卡住而產(chǎn)生的一種調(diào)用方式。類A的方法方法a()通過新起線程的方式調(diào)用類B的方法b(),代碼接著直接往下執(zhí)行,這樣無論方法b()執(zhí)行時(shí)間多久,都不會阻塞住方法a()的執(zhí)行。

但是這種方式,由于方法a()不等待方法b()的執(zhí)行完成,在方法a()需要方法b()執(zhí)行結(jié)果的情況下(視具體業(yè)務(wù)而定,有些業(yè)務(wù)比如啟異步線程發(fā)個(gè)微信通知、刷新一個(gè)緩存這種就沒必要),必須通過一定的方式對方法b()的執(zhí)行結(jié)果進(jìn)行監(jiān)聽。

在Java中,可以使用Future+Callable的方式做到這一點(diǎn),具體做法可以參見我的這篇文章Java多線程21:多線程下其他組件之CyclicBarrier、Callable、Future和FutureTask。

(3)回調(diào)

Java基礎(chǔ)9:解讀Java回調(diào)機(jī)制

最后是回調(diào),回調(diào)的思想是:

類A的a()方法調(diào)用類B的b()方法 類B的b()方法執(zhí)行完畢主動調(diào)用類A的callback()方法 這樣一種調(diào)用方式組成了上圖,也就是一種雙向的調(diào)用方式。

回調(diào)實(shí)例:Tom做題

數(shù)學(xué)老師讓Tom做一道題,并且Tom做題期間數(shù)學(xué)老師不用盯著Tom,而是在玩手機(jī),等Tom把題目做完后再把答案告訴老師。

1 數(shù)學(xué)老師需要Tom的一個(gè)引用,然后才能將題目發(fā)給Tom。

2 數(shù)學(xué)老師需要提供一個(gè)方法以便Tom做完題目以后能夠?qū)⒋鸢父嬖V他。

3 Tom需要數(shù)學(xué)老師的一個(gè)引用,以便Tom把答案給這位老師,而不是隔壁的體育老師。

回調(diào)接口,可以理解為老師接口

    //回調(diào)指的是A調(diào)用B來做一件事,B做完以后將結(jié)果告訴給A,這期間A可以做別的事情。
    //這個(gè)接口中有一個(gè)方法,意為B做完題目后告訴A時(shí)使用的方法。
    //所以我們必須提供這個(gè)接口以便讓B來回調(diào)。
    //回調(diào)接口,
    public interface CallBack {
        void tellAnswer(int res);
    }

數(shù)學(xué)老師類

    //老師類實(shí)例化回調(diào)接口,即學(xué)生寫完題目之后通過老師的提供的方法進(jìn)行回調(diào)。
    //那么學(xué)生如何調(diào)用到老師的方法呢,只要在學(xué)生類的方法中傳入老師的引用即可。
    //而老師需要指定學(xué)生答題,所以也要傳入學(xué)生的實(shí)例。
public class Teacher implements CallBack{
    private Student student;
    Teacher(Student student) {
        this.student = student;
    }
    void askProblem (Student student, Teacher teacher) {
        //main方法是主線程運(yùn)行,為了實(shí)現(xiàn)異步回調(diào),這里開啟一個(gè)線程來操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                student.resolveProblem(teacher);
            }
        }).start();
        //老師讓學(xué)生做題以后,等待學(xué)生回答的這段時(shí)間,可以做別的事,比如玩手機(jī).\
        //而不需要同步等待,這就是回調(diào)的好處。
        //當(dāng)然你可以說開啟一個(gè)線程讓學(xué)生做題就行了,但是這樣無法讓學(xué)生通知老師。
        //需要另外的機(jī)制去實(shí)現(xiàn)通知過程。
        // 當(dāng)然,多線程中的future和callable也可以實(shí)現(xiàn)數(shù)據(jù)獲取的功能。
        for (int i = 1;i < 4;i ++) {
            System.out.println("等學(xué)生回答問題的時(shí)候老師玩了 " + i + "秒的手機(jī)");
        }
    }
    @Override
    public void tellAnswer(int res) {
        System.out.println("the answer is " + res);
    }
}

學(xué)生接口

    //學(xué)生的接口,解決問題的方法中要傳入老師的引用,否則無法完成對具體實(shí)例的回調(diào)。
    //寫為接口的好處就是,很多個(gè)學(xué)生都可以實(shí)現(xiàn)這個(gè)接口,并且老師在提問題時(shí)可以通過
    //傳入List<Student>來聚合學(xué)生,十分方便。
public interface Student {
    void resolveProblem (Teacher teacher);
}

學(xué)生Tom

public class Tom implements Student{
    @Override
    public void resolveProblem(Teacher teacher) {
        try {
            //學(xué)生思考了3秒后得到了答案,通過老師提供的回調(diào)方法告訴老師。
            Thread.sleep(3000);
            System.out.println("work out");
            teacher.tellAnswer(111);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

測試類

public class Test {
    public static void main(String[] args) {
        //測試
        Student tom = new Tom();
        Teacher lee = new Teacher(tom);
        lee.askProblem(tom, lee);
        //結(jié)果
//        等學(xué)生回答問題的時(shí)候老師玩了 1秒的手機(jī)
//        等學(xué)生回答問題的時(shí)候老師玩了 2秒的手機(jī)
//        等學(xué)生回答問題的時(shí)候老師玩了 3秒的手機(jī)
//        work out
//        the answer is 111
    }
}

多線程中的“回調(diào)”

Java多線程中可以通過callable和future或futuretask結(jié)合來獲取線程執(zhí)行后的返回值。實(shí)現(xiàn)方法是通過get方法來調(diào)用callable的call方法獲取返回值。

其實(shí)這種方法本質(zhì)上不是回調(diào),回調(diào)要求的是任務(wù)完成以后被調(diào)用者主動回調(diào)調(diào)用者的接口。而這里是調(diào)用者主動使用get方法阻塞獲取返回值。

public class 多線程中的回調(diào) {
    //這里簡單地使用future和callable實(shí)現(xiàn)了線程執(zhí)行完后
    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";
            }
        });
        //手動阻塞調(diào)用get通過call方法獲得返回值。
        System.out.println(future.get());
        //需要手動關(guān)閉,不然線程池的線程會繼續(xù)執(zhí)行。
        executor.shutdown();
    //使用futuretask同時(shí)作為線程執(zhí)行單元和數(shù)據(jù)請求單元。
    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());
}
@Test
public void test () {
    Callable callable = new Callable() {
        @Override
        public Object call() throws Exception {
            return null;
        }
    };
    FutureTask futureTask = new FutureTask(callable);
}
}

網(wǎng)站題目:Java基礎(chǔ)9:解讀Java回調(diào)機(jī)制
文章源于:http://www.rwnh.cn/article48/jipohp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)網(wǎng)站收錄、品牌網(wǎng)站制作App開發(fā)、面包屑導(dǎo)航、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)
旬邑县| 黔江区| 驻马店市| 砀山县| 铅山县| 文登市| 报价| 根河市| 美姑县| 格尔木市| 乾安县| 汾阳市| 永宁县| 满城县| 东港市| 涿鹿县| 荆州市| 鞍山市| 延长县| 且末县| 小金县| 于都县| 新晃| 寿阳县| 宿迁市| 河间市| 郴州市| 邳州市| 大庆市| 呈贡县| 尼木县| 商河县| 蛟河市| 集安市| 都江堰市| 彰化县| 手机| 布拖县| 台北市| 靖边县| 大连市|