色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

Java中的回調(diào)

瀏覽:101日期:2022-08-26 14:44:38

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

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

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

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

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

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

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

先定義一個(gè)接口:.

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

定義一個(gè)Boss類實(shí)現(xiàn)這個(gè)接收?qǐng)?bào)告的接口:

public class Boss implements ReceiveReport{ private Worker worker; public Boss(Worker worker){ this.worker = worker; } /** * 下達(dá)任務(wù) */ public void sendTask(){ worker.work(this); } /** * 接收?qǐng)?bào)告 * @param name 員工名稱 * @param report 報(bào)告內(nèi)容 */ public void receiveReport(String name,String report){ System.out.println('收到:'+name+' 的報(bào)告:'+report); }}

定義一個(gè)Worker接口:

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

定義一個(gè)員工類。

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); }}

然后來測(cè)試一下:

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

測(cè)試結(jié)果:

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

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

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

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

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

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

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

/** * @author Frank * @create 2017/12/3 * @description 接收?qǐng)?bào)告接口 */public interface ReceiveReport { /** * 接收?qǐng)?bào)告 * @param worker 員工 * @param report 報(bào)告內(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)金獎(jiǎng)勵(lì)!'); } /** * 工作 * @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); } /** * 下達(dá)任務(wù) */ public void sendTask(String task){ //給各個(gè)員工依次下達(dá)任務(wù) for (Worker w:workers){ new Thread(new Runnable() {@Overridepublic void run() { w.work(task);} }).start(); } } /** * 接收?qǐng)?bào)告 * @param worker 員工 * @param report 報(bào)告內(nèi)容 */ public void receiveReport(Worker worker,String report){ int index = ++this.index; System.out.println(worker.getName()+'獲得第'+index+'名'); if (index <= 3){ //給前三名發(fā)獎(jiǎng)金 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();//定義一個(gè)Boss //定義十個(gè)員工 for (int i=0;i<10;i++){ Worker worker = new Employee('Employee['+i+']'); boss.addWorker(worker); } //boss開始下達(dá)任務(wù) boss.sendTask('Say Hello'); }}

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

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

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

因?yàn)槭褂昧硕嗑€程,所以每次運(yùn)行的結(jié)果可能都會(huì)不一樣,如果得到了不一樣的結(jié)果,那是很正常的現(xiàn)象。

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

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

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

以上就是Java中的回調(diào)的詳細(xì)內(nèi)容,更多關(guān)于Java 回調(diào)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 亚洲国产精品久久网午夜 | 黄视频在线免费 | 男人天堂成人 | 男女扒开双腿猛进入爽爽视频 | 国产三级网 | 国产精品大全 | 国产成人啪精品视频免费软件 | 三级视频在线播放 | 99久久免费国产香蕉麻豆 | 亚洲男人天堂 | 亚洲精品99久久一区二区三区 | 亚洲在线免费观看视频 | 久久欧美| 91精品久久久久久久久网影视 | 亚洲一区在线免费观看 | 二级黄的全免费视频 | 性夜黄a爽爽免费视频国产 性夜影院爽黄a爽免费看网站 | 久久久国产精品视频 | 亚洲图片在线视频 | 欧美巨大video粗暴 | 日本人一级毛片免费视频 | 国产成人一区二区视频在线观看 | 久久黄色视屏 | 中国黄色一级大片 | 美国黑人特大一级毛片 | 男人的天堂在线观看视频不卡 | 欧美高清在线视频在线99精品 | 成人做爰视频www | 国产精品无打码在线播放9久 | 91热国内精品永久免费观看 | 搞黄网站免费看 | 一级做a爰片久久毛片人呢 一级做a爰片久久毛片唾 | 欧美成人免费一区在线播放 | 久草久| 成年人性网站 | 欧美一级在线毛片免费观看 | 一区二区精品在线 | 国产精品视频免费观看调教网 | 曰本黄页 | 99精品福利视频在线一区 | 99热久久国产精品免费看 |