最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java調(diào)用回調(diào)機(jī)制詳解

 更新時(shí)間:2020年07月31日 14:32:36   作者:帶妳心菲  
這篇文章主要介紹了java調(diào)用回調(diào)機(jī)制詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

調(diào)用和回調(diào)機(jī)制

在一個(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í)行下去的, 這樣會(huì)造成整個(gè)流程的阻塞.

2.異步調(diào)用


異步調(diào)用是為了解決同步調(diào)用可能出現(xiàn)阻塞, 導(dǎo)致整個(gè)流程卡住而產(chǎn)生的一種調(diào)用方式. 類A的方法方法a()通過新起線程的方式調(diào)用類B的方法b(), 代碼接著直接往下執(zhí)行, 這樣無論方法b()執(zhí)行時(shí)間多久, 都不會(huì)阻塞住方法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多線程下的其他組件之CyclicBarrier、Callable、Future和FutureTask詳解

3.回調(diào):

如下圖所示, 回調(diào)是一種雙向的調(diào)用方式, 其實(shí)而言, 回調(diào)也有同步和異步之分, 講解中是同步回調(diào), 第二個(gè)例子使用的是異步回調(diào)


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

  • 類A的a()方法調(diào)用類B的b()方法
  • 類B的b()方法執(zhí)行完畢主動(dòng)調(diào)用類A的callback()方法

通俗而言: 就是A類中調(diào)用B類中的某個(gè)方法C, 然后B類中反過來調(diào)用A類中的方法D, D這個(gè)方法就叫回調(diào)方法, 這樣子說你是不是有點(diǎn)暈暈的, 其實(shí)我剛開始也是這樣不理解, 看了人家說比較經(jīng)典的回調(diào)方式:

  1. class A實(shí)現(xiàn)接口CallBack callback——背景1
  2. class A中包含一個(gè)class B的引用b ——背景2
  3. class B有一個(gè)參數(shù)為callback的方法f(CallBack callback) ——背景3
  4. A的對象a調(diào)用B的方法 f(CallBack callback) ——A類調(diào)用B類的某個(gè)方法 C
  5. 然后b就可以在f(CallBack callback)方法中調(diào)用A的方法 ——B類調(diào)用A類的某個(gè)方法D

回調(diào)的種類

回調(diào)分為同步回調(diào)和異步回調(diào), 假如以買彩票的場景來模擬, 我買彩票, 調(diào)用彩票網(wǎng),給我返回的結(jié)果確定是否中獎(jiǎng),同步回調(diào)就是,我買了彩票之后, 需要等待彩票網(wǎng)給我返回的結(jié)果, 這個(gè)時(shí)候我不能做其他事情, 我必須等待這個(gè)結(jié)果, 這就叫同步回調(diào), 同步, 就意味著等待, 我不能去做其他事情, 必須等待, 異步回調(diào)就是, 我買了彩票之后, 可以去做其他事情, 然后當(dāng)彩票網(wǎng)有了結(jié)果和消息, 再給我返回消息, 其中最明顯的方式就是在得到彩票結(jié)果的函數(shù)之中, 添加一個(gè)其他的方法, 如果我的其他方法可以立即執(zhí)行, 那么就是異步的(給出是否中獎(jiǎng)需要花費(fèi)很長的時(shí)間), 而在測試函數(shù)之中, 前后兩個(gè), 那是發(fā)生在測試函數(shù)的線程之中的, 肯定是一前一后按照次序的, 在這個(gè)地方不是顯示同步異步的地點(diǎn).

同步回調(diào)

同步回調(diào)和異步回調(diào), 主要體現(xiàn)在其是否需要等待. 同步調(diào)用, 如果被調(diào)用一方的APi(第三方API), 處理問題需要花很長時(shí)間, 我們需要等待, 那就是同步回調(diào), 如果調(diào)用完之后不需要理解得到結(jié)果, 我們調(diào)完就走, 去做其他事情, 那就是異步調(diào)用, 異步調(diào)用需要在我們調(diào)用第三方API處, 開啟一個(gè)新的線程即可, 而同步調(diào)用和平常的調(diào)用沒有任何區(qū)別.
例子
OrderResult接口, 其中的方法getOrderResult

public interface OrderResult {
 /**
 * 訂購貨物的狀態(tài)
 *
 * @param state
 * @return
 */
 //參數(shù)可以不用, 用不用按照自己的實(shí)際需求決定
 public String getOrderResult(String state);
}

Store類, 商店提供會(huì)無預(yù)定消息返回的接口, 回調(diào)OrderResult接口的方法, 給其返回預(yù)訂商品的狀態(tài), 重點(diǎn)是returnOrderGoodsInfo(OrderResult order)方法, 體現(xiàn)了回調(diào)的回. Store是被調(diào)用的一方, 被調(diào)用的一方, 要回過去調(diào)用調(diào)用一方的方法, 這個(gè)方法實(shí)際上是回調(diào)接口的方法.

public class Store {
 @Getter
 @Setter
 private String name;

 Store(String name) {
 this.name = name;
 }

 /*回調(diào)函數(shù), 將結(jié)構(gòu)傳給那個(gè)我們不能直接調(diào)用的方法, 然后獲取結(jié)果*/
 public String returnOrderGoodsInfo(OrderResult order) {
 String[] s = {"訂購中...", "訂購失敗", "即將發(fā)貨!", "運(yùn)輸途中...", "已在投遞"};
 Random random = new Random();
 int temp = random.nextInt(5);
 String s1 = s[temp];
 return order.getOrderResult(s1);
 }
}

SyncBuyer類, 同步顧客類, 其中獲取商品的訂購狀態(tài),orderGoods(), 調(diào)用了store返回商品調(diào)用信息的returnOrderGoodsInfo()方法, 但是在Store類的returnOrderGoodsInfo()方法之中, 以O(shè)rderResult接口為參數(shù), 反過來調(diào)用了OrderResult接口, 相當(dāng)于調(diào)用了其子類SyncBuyer本身, 以他為參數(shù), 調(diào)用了getOrderResult(String state)方法, 也就是OrderResult接口的方法, 相當(dāng)于就完成了一個(gè)調(diào)用的循環(huán), 然后取到了我們自己無法給出的結(jié)果.

這個(gè)地方的"循環(huán)", 是回調(diào)的關(guān)鍵所在, 需要正常調(diào)用其他外接提供方法來獲取結(jié)果的一方, 繼承一個(gè)回調(diào)接口, 實(shí)現(xiàn)它, 然后調(diào)用第三方的API方法, 第三方在我們調(diào)用的方法之中, 以回調(diào)結(jié)構(gòu)為參數(shù), 然后調(diào)用了接口中的方法, 其中可以返回相應(yīng)的結(jié)果給我們, 需要說明的是, 我們雖然實(shí)現(xiàn)了這個(gè)接口的方法, 但是我們自己的類之中, 或者說此類本身, 卻沒法調(diào)用這個(gè)方法, 也可以說, 此類調(diào)用這個(gè)方法是不會(huì)產(chǎn)生有效的結(jié)果的. 回調(diào)的回, 就體現(xiàn)在此處, 在Store類之中的returnOrderGoodsInfo(OrderResult order)方法之中, 得到了很好的體現(xiàn).

/*同步, 顧客在商店預(yù)訂商品, 商店通知顧客預(yù)訂情況*/
public class SyncBuyer implements OrderResult {
 @Getter
 @Setter
 private Store store;//商店
 @Getter
 @Setter
 private String buyerName;//購物者名
 @Getter
 @Setter
 private String goodsName;//所購商品名

 SyncBuyer(Store store, String buyerName, String goodsName) {
 this.store = store;
 this.buyerName = buyerName;
 this.goodsName = goodsName;
 }

 /*調(diào)用從商店返回訂購物品的信息*/
 public String orderGoods() {
 String goodsState = store.returnOrderGoodsInfo(this);
 System.out.println(goodsState);
 myFeeling();// 測試同步還是異步, 同步需要等待, 異步無需等待
 return goodsState;

 }

 public void myFeeling() {
 String[] s = {"有點(diǎn)小激動(dòng)", "很期待!", "希望是個(gè)好貨!"};
 Random random = new Random();
 int temp = random.nextInt(3);
 System.out.println("我是" + this.getBuyerName() + ", 我現(xiàn)在的感覺: " + s[temp]);
 }

 /*被回調(diào)的方法, 我們自己不去調(diào)用, 這個(gè)方法給出的結(jié)果, 是其他接口或者程序給我們的, 我們自己無法產(chǎn)生*/
 @Override
 public String getOrderResult(String state) {
 return "在" + this.getStore().getName() + "商店訂購的" + this.getGoodsName() + "玩具, 目前的預(yù)訂狀態(tài)是: " + state;
 }
}

Test2Callback類, 測試同步回調(diào)的結(jié)果,

public class Test2Callback {
 public static void main(String[] args) {
 Store wallMart = new Store("沙中路沃爾瑪");
 SyncBuyer syncBuyer = new SyncBuyer(wallMart, "小明", "超能鐵扇公主");
 System.out.println(syncBuyer.orderGoods());
 }
}

異步回調(diào)

同步回調(diào)和異步回調(diào)的代碼層面的差別就是是否在我們調(diào)用第三方的API處, 為其開辟一條新的線程, 其他并無差異
例子
OrderResult接口, 其中的方法getOrderResult

public interface OrderResult {
 /**
 * 訂購貨物的狀態(tài)
 *
 * @param state
 * @return
 */
 //參數(shù)可以不用, 用不用按照自己的實(shí)際需求決定
 public String getOrderResult(String state);
}

Store類, 商店提供會(huì)無預(yù)定消息返回的接口, 回調(diào)OrderResult接口的方法, 給其返回預(yù)訂商品的狀態(tài).

public class Store {
 @Getter
 @Setter
 private String name;

 Store(String name) {
 this.name = name;
 }

 /*回調(diào)函數(shù), 將結(jié)構(gòu)傳給那個(gè)我們不能直接調(diào)用的方法, 然后獲取結(jié)果*/
 public String returnOrderGoodsInfo(OrderResult order) {
 String[] s = {"訂購中...", "訂購失敗", "即將發(fā)貨!", "運(yùn)輸途中...", "已在投遞"};
 Random random = new Random();
 int temp = random.nextInt(5);
 String s1 = s[temp];
 return order.getOrderResult(s1);
 }
}

NoSyncBuyer類, 異步調(diào)用Store類的returnOrderGoodsInfo(OrderResult order)方法, 來返回商品轉(zhuǎn)改的結(jié)果.

/*異步*/
@Slf4j
public class NoSyncBuyer implements OrderResult {
 @Getter
 @Setter
 private Store store;//商店
 @Getter
 @Setter
 private String buyerName;//購物者名
 @Getter
 @Setter
 private String goodsName;//所購商品名

 NoSyncBuyer(Store store, String buyerName, String goodsName) {
 this.store = store;
 this.buyerName = buyerName;
 this.goodsName = goodsName;
 }

 /*調(diào)用從商店返回訂購物品的信息*/
 public String orderGoods() {
 String goodsState = "--";
 MyRunnable mr = new MyRunnable();
 Thread t = new Thread(mr);
 t.start();
 System.out.println(goodsState);
 goodsState = mr.getResult();// 得到返回值
 myFeeling();// 用來測試異步是不是還是按順序的執(zhí)行
 return goodsState;
 }

 public void myFeeling() {
 String[] s = {"有點(diǎn)小激動(dòng)", "很期待!", "希望是個(gè)好貨!"};
 Random random = new Random();
 int temp = random.nextInt(3);
 System.out.println("我是" + this.getBuyerName() + ", 我現(xiàn)在的感覺: " + s[temp]);
 }

 /*被回調(diào)的方法, 我們自己不去調(diào)用, 這個(gè)方法給出的結(jié)果, 是其他接口或者程序給我們的, 我們自己無法產(chǎn)生*/
 @Override
 public String getOrderResult(String state) {
 return "在" + this.getStore().getName() + "商店訂購的" + this.getGoodsName() + "玩具, 目前的預(yù)訂狀態(tài)是: " + state;
 }

 // 開啟另一個(gè)線程, 但是沒有返回值, 怎么回事
 // 調(diào)試的時(shí)候, 等待一會(huì)兒, 還是可以取到值, 但不是立即取到, 在print顯示的時(shí)候, 卻是null, 需要注意?
 private class MyRunnable implements Runnable {
 @Getter
 @Setter
 private String result;

 @Override
 public void run() {
  try {
  Thread.sleep(10000);
  result = store.returnOrderGoodsInfo(NoSyncBuyer.this);// 匿名函數(shù)的時(shí)候, 無法return 返回值
  } catch (InterruptedException e) {
  log.error("出大事了, 異步回調(diào)有問題了", e);
  }
 }
 }
}

Test2Callback類, 測試同步回調(diào)和異步回調(diào)的結(jié)果.

public class Test2Callback {
 public static void main(String[] args) {
 Store wallMart = new Store("沙中路沃爾瑪");
 SyncBuyer syncBuyer = new SyncBuyer(wallMart, "小明", "超能鐵扇公主");
 System.out.println(syncBuyer.orderGoods());


 System.out.println("\n");
 Store lawson = new Store("沙中路羅森便利店");
 NoSyncBuyer noSyncBuyer = new NoSyncBuyer(lawson, "cherry", "變形金剛");
 System.out.println(noSyncBuyer.orderGoods());
 }
}

到此這篇關(guān)于java調(diào)用回調(diào)機(jī)制詳解的文章就介紹到這了,更多相關(guān)java調(diào)用回調(diào)機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java如何實(shí)現(xiàn)保證線程安全

    Java如何實(shí)現(xiàn)保證線程安全

    這篇文章主要介紹了Java如何實(shí)現(xiàn)保證線程安全問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 詳解Java中使用ImageIO類對圖片進(jìn)行壓縮的方法

    詳解Java中使用ImageIO類對圖片進(jìn)行壓縮的方法

    這篇文章主要介紹了Java中使用ImageIO類對圖片進(jìn)行壓縮的方法,能夠按指定的比例調(diào)整圖片的寬高,需要的朋友可以參考下
    2016-04-04
  • SpringBoot中Get請求和POST請求接收參數(shù)示例詳解

    SpringBoot中Get請求和POST請求接收參數(shù)示例詳解

    文章詳細(xì)介紹了SpringBoot中Get請求和POST請求的參數(shù)接收方式,包括方法形參接收參數(shù)、實(shí)體類接收參數(shù)、HttpServletRequest接收參數(shù)、@PathVariable接收參數(shù)、數(shù)組參數(shù)接收、集合參數(shù)接收、Map接收參數(shù)以及通過@RequestBody接收J(rèn)SON格式的參數(shù),感興趣的朋友一起看看吧
    2024-12-12
  • java  Super 用法詳解及實(shí)例代碼

    java Super 用法詳解及實(shí)例代碼

    這篇文章主要介紹了java Super 用法詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • jenkins+maven+svn自動(dòng)部署和發(fā)布的詳細(xì)圖文教程

    jenkins+maven+svn自動(dòng)部署和發(fā)布的詳細(xì)圖文教程

    Jenkins是一個(gè)開源的、可擴(kuò)展的持續(xù)集成、交付、部署的基于web界面的平臺(tái)。這篇文章主要介紹了jenkins+maven+svn自動(dòng)部署和發(fā)布的詳細(xì)圖文教程,需要的朋友可以參考下
    2020-09-09
  • 教你用JAVA寫文本編輯器(四)

    教你用JAVA寫文本編輯器(四)

    這篇文章主要給大家介紹了關(guān)于用JAVA寫文本編輯器的相關(guān)資料,通過這篇文章你可以完整的知道利用JAVA寫文本編輯器的完整過程,需要的朋友可以參考下
    2021-11-11
  • java后臺(tái)實(shí)現(xiàn)js關(guān)閉本頁面,父頁面指定跳轉(zhuǎn)或刷新操作

    java后臺(tái)實(shí)現(xiàn)js關(guān)閉本頁面,父頁面指定跳轉(zhuǎn)或刷新操作

    這篇文章主要介紹了java后臺(tái)實(shí)現(xiàn)js關(guān)閉本頁面,父頁面指定跳轉(zhuǎn)或刷新操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java面試題沖刺第十五天--設(shè)計(jì)模式

    Java面試題沖刺第十五天--設(shè)計(jì)模式

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于設(shè)計(jì)模式的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 深入了解Java并發(fā)AQS的獨(dú)占鎖模式

    深入了解Java并發(fā)AQS的獨(dú)占鎖模式

    AQS是一種提供了原子式管理同步狀態(tài)、阻塞和喚醒線程功能以及隊(duì)列模型的簡單框架。一般來說,同步工具實(shí)現(xiàn)鎖的控制分為獨(dú)占鎖和共享鎖,而AQS提供了對這兩種模式的支持。本文主要來介紹一下獨(dú)占鎖模式,需要的可以參考一下
    2022-10-10
  • RocketMQ存儲(chǔ)文件的實(shí)現(xiàn)

    RocketMQ存儲(chǔ)文件的實(shí)現(xiàn)

    這篇文章主要介紹了RocketMQ存儲(chǔ)文件的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論

黑河市| 新干县| 垦利县| 宁河县| 普兰县| 玉环县| 从江县| 云安县| 宁河县| 荣成市| 中江县| 霍山县| 民和| 同心县| 鹰潭市| 焦作市| 宁安市| 宝丰县| 房产| 平度市| 大厂| 湘潭县| 墨江| 漳州市| 儋州市| 河津市| 平阴县| 内乡县| 平远县| 崇文区| 镶黄旗| 左权县| 涿鹿县| 健康| 遵化市| 屏边| 教育| 玛多县| 永春县| 同江市| 方山县|