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

Java中的回調(diào)

 更新時間:2020年08月21日 09:06:07   作者:弗蘭克的貓  
這篇文章主要介紹了Java中回調(diào)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)java,感興趣的朋友可以了解下

  又忙了一周,事情差不多解決了,終于有可以繼續(xù)寫我的博客了(各位看官久等了)。

  這次我們來談一談Java里的一個很有意思的東西——回調(diào)。

  什么叫回調(diào),一本正經(jīng)的來講,在計算機程序設(shè)計中,回調(diào)函數(shù)是指通過函數(shù)參數(shù)傳遞到其它代碼的,某一塊可執(zhí)行代碼的引用。這一設(shè)計允許了底層代碼調(diào)用在高層定義的子程序。

  別急別急,且聽我慢慢道來。

  舉個栗子,設(shè)置這樣一個情景,老板安排員工做事,然后讓他做完后跟他電話說一聲。老板當(dāng)然不會在那里一直等員工做完事情才去做其他事,而是只交代完任務(wù)就去忙自己的事情了。

  這個例子包含了異步+回調(diào)的思想,員工做完任務(wù)后向老板報告這個過程,就叫回調(diào),當(dāng)然,報告的話,老板肯定先跟員工說好了報告方式,比如說郵件,電話等,而交代報告方式,就是注冊回調(diào)函數(shù),這里的回調(diào)函數(shù)必須符合接口的規(guī)范。

  好像還是有些不明白?來上代碼吧。

  先定義一個接口:.

public interface ReceiveReport {
  /**
   * 接收報告
   * @param name 員工名稱
   * @param report 報告內(nèi)容
   */
  public void receiveReport(String name,String report);
}

  定義一個Boss類實現(xiàn)這個接收報告的接口:

public class Boss implements ReceiveReport{
  private Worker worker;

  public Boss(Worker worker){
    this.worker = worker;
  }

  /**
   * 下達任務(wù)
   */
  public void sendTask(){
    worker.work(this);
  }

  /**
   * 接收報告
   * @param name 員工名稱
   * @param report 報告內(nèi)容
   */
  public void receiveReport(String name,String report){
    System.out.println("收到:"+name+" 的報告:"+report);
  }
}

  定義一個Worker接口:

public interface Worker {
  public void work(ReceiveReport boss);
}

  定義一個員工類。

public class Employee implements Worker{
  private String name;//員工姓名

  //構(gòu)造器
  public Employee(String name) {
    this.name = name;
  }

  /**
   * 工作
   * @param boss 任務(wù)名稱
   */
  public void work(ReceiveReport boss){
    System.out.println(name + " is doing works.");
    String report = "我已經(jīng)完成了任務(wù)!";
    boss.receiveReport(name,report);
  }
}

  然后來測試一下:

public class Test {
  public static void main(String[] args) {
    Worker employee = new Employee("Frank");//定義一個員工
    Boss boss = new Boss(employee);//定義一個Boss
    //boss開始下達任務(wù)
    boss.sendTask();
  }
}

  測試結(jié)果:

Frank is doing works.收到:Frank 的報告:我已經(jīng)完成了任務(wù)!

  至此,員工與老板的交互就完成了,這就是一個簡單的同步回調(diào)了。Boss通過Worker接口可以給員工安排工作,而不用去關(guān)心是哪個員工在工作,Worker通過ReceiveReport來向Boss報告工作情況,兩個類通過接口進行回調(diào)交互,可以很好的解耦合,因為Boss可以安排不同的員工,只要他們實現(xiàn)了Worker接口就行,而員工也可以向不同的boss匯報情況,只要實現(xiàn)了ReceiveReport接口即可。

其實回調(diào)的核心思想就是把自身的this指針傳給調(diào)用方,就像這里把employee傳入Boss類中,在work方法中又注冊了回調(diào),于是兩者的交互性就很強了。

  那么為什么要用回調(diào)呢?如果Boss要在員工完成工作之前登記員工的一些信息,如姓名等,那么有了回調(diào)機制,通過把this指針傳入,就能在Boss內(nèi)部為所欲為了,而不需要通過設(shè)計新的方法來獲取,而且需要獲得的數(shù)據(jù)越多,回調(diào)的優(yōu)勢越明顯。

  其實這里只是簡單的一對一關(guān)系,如果是一個Boss,多個員工,那就是簡單的觀察者模式,如果是多個Boss多個員工,那就是簡單生產(chǎn)者-消費者模式了。

  當(dāng)然,這里僅僅是簡單的同步回調(diào)。員工只能一個接一個的去完成任務(wù),也就是說前一個員工必須等待后一個員工完成任務(wù)后才能開始任務(wù),事實上,員工一般是同時進行工作的。

  如果換一個場景,現(xiàn)在有十個員工,老板發(fā)布任務(wù),前三名完成的人有獎金獎勵,那么就需要用到異步回調(diào)了,sendTask的時候使用線程即可,我們來修改一下代碼:

/**
 * @author Frank
 * @create 2017/12/3
 * @description 接收報告接口
 */
public interface ReceiveReport {
  /**
   * 接收報告
   * @param worker 員工
   * @param report 報告內(nèi)容
   */
  public void receiveReport(Worker worker,String report);
}
/**
 * @author Frank
 * @create 2017/12/3
 * @description 工人接口
 */
public interface Worker {
  public void work(String taskName);
  public void setReceiveReport(ReceiveReport boss);
  public void getReward(Double money);
  public String getName();
}
import java.util.Random;

/**
 * @author Frank
 * @create 2017/12/3
 * @description 員工類
 */
public class Employee implements Worker{
  private ReceiveReport boss;
  private String name;//員工姓名

  @Override
  public String getName() {
    return name;
  }

  //構(gòu)造器
  public Employee(String name) {
    this.name = name;
  }

  public void setReceiveReport(ReceiveReport boss) {
    this.boss = boss;
  }

  @Override
  public void getReward(Double money) {
    System.out.println(name+"由于表現(xiàn)突出,獲得$"+money+"現(xiàn)金獎勵!");
  }

  /**
   * 工作
   * @param taskName 任務(wù)名稱
   */
  public void work(String taskName){
    System.out.println(name + " is doing works:"+taskName);
    Random random = new Random();
    Integer time = random.nextInt(10000);
    try {
      Thread.sleep(time);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    String report = "順利完成任務(wù)!";
    //通知老板
    boss.receiveReport(this,report);
  }
}
import java.util.ArrayList;
import java.util.List;

/**
 * @author Frank
 * @create 2017/12/3
 * @description Boss類
 */
public class Boss implements ReceiveReport{
  private List<Worker> workers = new ArrayList<>();//老板管理的員工
  private volatile int index;//順序

  /**
   * 添加員工
   * @param worker 員工
   */
  public void addWorker(Worker worker){
    workers.add(worker);
    worker.setReceiveReport(this);
  }

  /**
   * 下達任務(wù)
   */
  public void sendTask(String task){
    //給各個員工依次下達任務(wù)
    for (Worker w:workers){
      new Thread(new Runnable() {
        @Override
        public void run() {
          w.work(task);
        }
      }).start();
    }
  }

  /**
   * 接收報告
   * @param worker 員工
   * @param report 報告內(nèi)容
   */
  public void receiveReport(Worker worker,String report){
    int index = ++this.index;
    System.out.println(worker.getName()+"獲得第"+index+"名");
    if (index <= 3){
      //給前三名發(fā)獎金
      worker.getReward(1000.0*(4-index));
    }
  }
}
/**
 * @author Frank
 * @create 2017/12/3
 * @description
 */
public class Test {
  public static void main(String[] args) {
    Boss boss = new Boss();//定義一個Boss
    //定義十個員工
    for (int i=0;i<10;i++){
      Worker worker = new Employee("Employee["+i+"]");
      boss.addWorker(worker);
    }
    //boss開始下達任務(wù)
    boss.sendTask("Say Hello");

  }
}

  這里沒有使用鎖,因為設(shè)置的時間間隔區(qū)間為0-10s,發(fā)生并發(fā)沖突的概率很低,而且由于現(xiàn)在還沒有說多線程的內(nèi)容,所以暫時先不使用。只需要知道在sendTask方法中,依次啟動了線程來調(diào)用每個Worker的work方法,線程啟動后會同時執(zhí)行,執(zhí)行完畢后,又會調(diào)用Boss的receiveReport方法來向Boss反饋結(jié)果,接收結(jié)果后,根據(jù)完成順序,再調(diào)用Worker的getReward方法來給前三名發(fā)獎金。其實這里是雙向回調(diào)了,Boss把this指針傳給了Worker,Worker又把自己的this指針傳給了Worker。

  程序執(zhí)行結(jié)果如下:

Employee[0] is doing works:Say Hello
Employee[4] is doing works:Say Hello
Employee[3] is doing works:Say Hello
Employee[2] is doing works:Say Hello
Employee[1] is doing works:Say Hello
Employee[5] is doing works:Say Hello
Employee[7] is doing works:Say Hello
Employee[6] is doing works:Say Hello
Employee[9] is doing works:Say Hello
Employee[8] is doing works:Say Hello
Employee[9]獲得第1名
Employee[9]由于表現(xiàn)突出,獲得$3000.0現(xiàn)金獎勵!
Employee[7]獲得第2名
Employee[7]由于表現(xiàn)突出,獲得$2000.0現(xiàn)金獎勵!
Employee[3]獲得第3名
Employee[3]由于表現(xiàn)突出,獲得$1000.0現(xiàn)金獎勵!
Employee[1]獲得第4名
Employee[0]獲得第5名
Employee[5]獲得第6名
Employee[4]獲得第7名
Employee[8]獲得第8名
Employee[6]獲得第9名
Employee[2]獲得第10名

  因為使用了多線程,所以每次運行的結(jié)果可能都會不一樣,如果得到了不一樣的結(jié)果,那是很正常的現(xiàn)象。

  舉了這兩個栗子,對回調(diào)應(yīng)該也有了一定的了解了吧。

  其實回調(diào)只是一種思想,并不是java中獨有的內(nèi)容,思想這種東西,是為了解決特定場景下的特定問題而出現(xiàn)的,只有被正確應(yīng)用了才有它的價值,而不要為了使用它而使用它。

  至此,回調(diào)講解完畢,如有說明有誤的地方,歡迎各位批評指正。也歡迎大家繼續(xù)關(guān)注。

以上就是Java中的回調(diào)的詳細內(nèi)容,更多關(guān)于Java 回調(diào)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 簡單的一次springMVC路由跳轉(zhuǎn)實現(xiàn)

    簡單的一次springMVC路由跳轉(zhuǎn)實現(xiàn)

    本文主要介紹了springMVC路由跳轉(zhuǎn)實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Java Swing JList列表框的實現(xiàn)

    Java Swing JList列表框的實現(xiàn)

    這篇文章主要介紹了Java Swing JList列表框的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • java 中RSA的方式實現(xiàn)非對稱加密的實例

    java 中RSA的方式實現(xiàn)非對稱加密的實例

    這篇文章主要介紹了java 中RSA的方式實現(xiàn)非對稱加密的實例的相關(guān)資料,這里提供實例幫助大家理解這部分知識,需要的朋友可以參考下
    2017-08-08
  • 詳解ThreadLocal為什么會內(nèi)存溢出原理

    詳解ThreadLocal為什么會內(nèi)存溢出原理

    這篇文章主要為大家介紹了ThreadLocal為什么會內(nèi)存溢出原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Java spring單點登錄系統(tǒng)

    Java spring單點登錄系統(tǒng)

    這篇文章主要介紹了Java spring單點登錄系統(tǒng),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • spring-boot-maven-plugin?配置有啥用

    spring-boot-maven-plugin?配置有啥用

    這篇文章主要介紹了spring-boot-maven-plugin?配置是干啥的,這個是SpringBoot的Maven插件,主要用來打包的,通常打包成jar或者war文件,本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • 簡單聊一聊Java線程池ThreadPoolExecutor

    簡單聊一聊Java線程池ThreadPoolExecutor

    在使用線程池之后,開啟線程就變成了在線程池當(dāng)中找到一個空閑的線程,銷毀線程變成了歸還線程到線程池的過程,下面這篇文章主要給大家介紹了關(guān)于Java線程池ThreadPoolExecutor的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Spring Boot使用AOP在指定方法執(zhí)行完后執(zhí)行異步處理操作

    Spring Boot使用AOP在指定方法執(zhí)行完后執(zhí)行異步處理操作

    這篇文章主要介紹了Spring Boot使用AOP在指定方法執(zhí)行完后執(zhí)行異步處理操作,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2024-06-06
  • Java中八大包裝類舉例詳解(通俗易懂)

    Java中八大包裝類舉例詳解(通俗易懂)

    這篇文章主要介紹了Java中的包裝類,包括它們的作用、特點、用途以及如何進行裝箱和拆箱,包裝類還提供了許多實用方法,如轉(zhuǎn)換、獲取基本類型值、比較和類型檢測,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-02-02
  • SpringBoot 圖書管理系統(tǒng)(刪除、強制登錄、更新圖書)詳細代碼

    SpringBoot 圖書管理系統(tǒng)(刪除、強制登錄、更新圖書)詳細代碼

    在企業(yè)開發(fā)中,通常不采用delete語句進行物理刪除,而是使用邏輯刪除,邏輯刪除通過修改標識字段來表示數(shù)據(jù)已被刪除,方便數(shù)據(jù)恢復(fù),本文給大家介紹SpringBoot 圖書管理系統(tǒng)實例代碼,感興趣的朋友跟隨小編一起看看吧
    2024-09-09

最新評論

阿拉善左旗| 启东市| 伊吾县| 交口县| 灵川县| 康马县| 海兴县| 霍州市| 理塘县| 红安县| 黄山市| 张家界市| 郴州市| 梧州市| 河西区| 称多县| 阿勒泰市| 榆树市| 曲靖市| 深州市| 鄂尔多斯市| 阜新市| 阳新县| 凌源市| 长丰县| 荆州市| 黄冈市| 东乡县| 洪洞县| 古浪县| 石阡县| 普安县| 若尔盖县| 文水县| 平度市| 湟源县| 宣城市| 乳源| 无锡市| 普安县| 蒲江县|