调用和回调机制。在一个应用系统中,无论用什么语言开发,模块之间都必须有调用。有几种调用方式:1。同步调用同步调用是最基本、最简单的调用方式。A类的方法a()调用B类的方法b(),一直等到b()方法执行完毕,a()方法继续往下走。这种调用方式适用于方法b()执行时间不长的情况,因为如果b()方法执行时间长或者直接阻塞,a()方法剩余的代码就无法执行,这会造成整个流程的Blocking。2.异步调用异步调用是解决同步调用可能阻塞,导致整个流程卡住的一种调用方式。A类的方法方法a()通过新线程调用B类方法的方法b(),然后直接执行代码,这样不管方法b()的执行时间多长,方法a()的执行不会被阻塞。但是这样,由于方法a()不会等待方法b()执行完成,在方法a()需要方法b()的执行结果的情况下(根据具体业务,有的业务比如启动异步线程发送微信通知或者刷新缓存都不需要),必须通过某种方式监听方法b()的执行结果。在Java中,您可以使用Future+Callable来执行此操作。详情请参考文章:http://www.cnblogs.com/xrq730/p/4872722.html3。回调如下图所示。回调是一种双向调用方式。其实回调也可以分为同步和异步。解释中是同步回调。第二个例子使用异步回调。callback的思路是:A类的a()方法调用B类的b()方法,B类的b()方法执行完毕后,主动调用C类的callback()方法,然后B类依次调用A类中的方法D。方法D称为回调方法。说头晕是不是有点头晕?其实一开始我也不懂。我看过比较经典的回调方法:A类实现了接口CallBack回调-后台1A类包含B类的引用b-后台2B类有一个方法f(CallBackcallback),参数是callback-后台3A的对象a调用B的方法f(CallBackcallback)——A类调用B类的一个方法方法D中的回调有两种,回调分为同步回调和异步回调。如果我们模拟买彩票的场景,我买彩票,调用彩票网,把结果返回给我,判断我有没有中奖。同步回调是我买完彩票后,需要等待彩票网返回的结果。我现在不能做其他事情。我必须等待结果。这称为同步回调。同步意味着等待。我不能做其他事情,必须等待。异步回调就是我买了彩票之后,我可以做其他的事情,然后当彩票网有结果和消息的时候,它会给我返回一个消息。最明显的方式就是加一个other的方法,如果我的other的方法可以立即执行,就是异步的(要等很久才给是否中奖),而在测试函数中,前后两个,那是在测试函数的线程中发生的,一定是依次发生的。这个地方不是展示同步和异步的地方。同步回调和异步回调主要体现在是否需要等待。同步调用,如果是被调用方的API(第三方API),处理问题的时间比较长,我们需要等待,那就是同步回调,如果不需要理解并得到结果调用完我们调用完就离开,去做其他的事情,就是异步调用,异步调用需要在我们调用第三方API的时候,新开一个线程就行,和同步调用没有区别普通电话。OrderResult接口实例,方法getOrderResultpublicinterfaceOrderResult{/***订单商品状态**@paramstate*@return*///参数可不可用,根据你的实际需要决定publicStringgetOrderResult(Stringstate);}Store类,store提供了一个不返回预定消息的接口,回调OrderResult接口的方法,将订购商品的状态返回给它,关键点是returnOrderGoodsInfo(OrderResultorder)方法,体现回调的返回.Store是被调用方,被调用方需要回去调用调用方的方法。这个方法其实就是一个回调接口方法。publicclassStore{@Getter@SetterprivateStringname;Store(Stringname){this.name=name;}/*回调函数,把结构传给我们不能直接调用的方法,然后得到结果*/publicStringreturnOrderGoodsInfo(OrderResultorder){String[]s={"正在订购...","订购失败","即将发货!","运输中...","已经在投中Delivery"};Randomrandom=newRandom();inttemp=random.nextInt(5);Stringss1=s[temp];returnorder.getOrderResult(s1);}}SyncBuyer类,同步客户类,获取商品的订单状态,orderGoods(),调用store的returnOrderGoodsInfo()方法返回商品调用信息,但是在Store类的returnOrderGoodsInfo()方法中,以OrderResult接口为参数,依次调用OrderResult接口,相当于调用它的子类SyncBuyer本身,以它为参数,调用getOrderResult(Stringstate)方法,也就是OrderResult接口的方法,相当于完成一个调用周期,然后得到结果不能自己给,这个地方的“循环”,是回调的关键,需要调用其他外部方法获取结果的一方,一般会继承一个回调接口,实现它,然后调用API方法第三方的。T第三方在我们调用的方法中将回调结构作为参数,然后调用接口中的方法,可以返回相应的结果给我们。需要注意的是,虽然我们实现了这个接口的方法,但是我们不能在自己的类中,或者类本身调用这个方法,也可以说这种类型的调用这个方法是不会产生有效结果的。回调的返回体现在这里,在Store类中的returnOrderGoodsInfo(OrderResultorder)方法中,很好的体现了./*同步,客户在店内订购商品,店家通知客户预订状态*/publicclassSyncBuyerimplementsOrderResult{@Getter@SetterprivateStorestore;//Store@Getter@SetterprivateStringbuyerName;//ShopperName@Getter@SetterprivateStringgoodsName;//购买商品名称SyncBuyer(Storestore,StringbuyerName,StringgoodsName){this.store=store;this.buyerName=buyerName;this.goodsName=goodsName;}/*调用从商店返回订单商品信息*/publicStringorderGoods(){StringgoodsState=store.returnOrderGoodsInfo(this);System.out.println(goodsState);myFeeling();//测试同步或异步,同步需要等待,异步不需要等待","希望是个好产品!"};Randomrandom=newRandom();inttemp=random.nextInt(3);System.out.println("我是"+this.getBuyerName()+",我的感受now:"+s[temp]);}/*是我们自己不调用回调方法。这个方法给出的结果是其他接口或者程序给我们的。我们不能生成*/@OverridepublicStringgetOrderResult(Stringstate){return"in"+this.getStore().getName()+"+this.getGoodsName()+"商店订购的玩具,当前预订状态为:"+state;}}Test2Callback类,测试同步回调的结果,publicclassTest2Callback{publicstaticvoidmain(String[]args){StorewallMart=newStore("沙中路沃尔玛");SyncBuyersyncBuyer=newSyncBuyer(wallMart,"小明","超级公主"铁扇");System.out.println(syncBuyer.orderGoods());}}异步回调同步回调和异步回调在代码层面的区别在于我们是否调用了第三方API,对于新开一个线程,和其他的没什么区别回复Java小伙伴公众号里的“面试题汇总”,送你面试题实例合集OrderResult接口,方法getOrderResultpublicinterfaceOrderResult{/***orderstatus**@paramstate*@return*///参数可以否,您需要根据您的实际需要来决定。publicStringgetOrderResult(Stringstate);}Store类,store提供了一个不返回预定消息的接口,回调OrderResult接口的方法,返回订购商品的状态。publicclassStore{@Getter@SetterprivateStringname;Store(Stringname){this.name=name;}/*回调函数,将结构传给我们不能直接调用的方法,然后得到结果*/publicStringreturnOrderGoodsInfo(OrderResultorder){String[]s={"ordering...","订单失败","即将发货!","运输中...","已发货"};Randomrandom=newRandom();inttemp=random.nextInt(5);Stringss1=s[temp];returnorder.getOrderResult(s1);}}NoSyncBuyer类,异步调用Store类的returnOrderGoodsInfo(OrderResultorder)方法返回商品转换结果。/*异步*/@Slf4jpublicclassNoSyncBuyerimplementsOrderResult{@Getter@SetterprivateStorestore;//store@Getter@SetterprivateStringbuyerName;//购物者名称@Getter@SetterprivateStringgoodsName;//购买商品名称NoSyncBuyer(Storestore,StringbuyerName,StringgoodsName){this.store=store;this.buyerName=buyerName;this.goodsName=goodsName;}/*调用以从商店返回有关订购商品的信息*/publicStringorderGoods(){StringgoodsState="--";MyRunnablemr=newMyRunnable();Threadt=newThread(mr);t.start();System.out.println(goodsState);goodsState=mr.getResult();//获取返回值myFeeling();//用来测试是异步执行还是顺序执行returngoodsState;}publicvoidmyFeeling(){String[]s={"有点小激动","好期待!","希望是个好产品!"};Randomrandom=newRandom();inttemp=random.nextInt(3);System.out.println("我是"+this.getBuyerName()+",我现在的感受:"+s[temp]);}/*被回调的方法,我们做不能自己调用??,这个方法给出的结果是其他接口或者程序给我们的,我们不能生成*/@OverridepublicStringgetOrderResult(Stringstate){return""+this.getGoodsName()+"toysorderedat"+this.getStore().getName()+"store,当前保留状态为:"+state;}//开始一个nother线程,但是没有返回值,怎么回事//调试的时候,等一会,还是可以拿到值的,但是不是马上,打印的时候显示,有时候是null,需要注意一下?privateclassMyRunnableimplementsRunnable{@Getter@SetterprivateStringresult;@Overridepublicvoidrun(){try{Thread.sleep(10000);result=store.returnOrderGoodsInfo(NoSyncBuyer.this);//使用匿名函数时,无法返回返回值}catch(InterruptedExceptione){log.error("出错了,异步回调有问题",e);}}}}Test2Callback类,测试同步回调和异步回调的结果。publicclassTest2Callback{publicstaticvoidmain(String[]args){StorewallMart=newStore("沙中路沃尔玛");SyncBuyersyncBuyer=newSyncBuyer(wallMart,"小明","超级铁扇公主");System.out.println(syncBuyer.orderGoods());System.out.println("\n");Storelawson=newStore("沙中路罗森便利店");NoSyncBuyernoSyncBuyer=newNoSyncBuyer(lawson,"cherry","变形金刚");System.out.println(noSyncBuyer.orderGoods());}}
