日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程实现异步调用

發布時間:2023/12/18 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程实现异步调用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Java平臺,實現異步調用的角色有如下三個角色:調用者、 提貨單 、真實數據,一個調用者在調用耗時操作,不能立即返回數據時,先返回一個提貨單

.然后在過一斷時間后憑提貨單來獲取真正的數據.去蛋糕店買蛋糕,不需要等蛋糕做出來(假設現做要很長時間),只需要領個提貨單就可以了(去干別的

事情),等到蛋糕做好了,再拿提貨單取蛋糕就可以了。

[java]?view plaincopy print?
  • package?com.somnus.async;??
  • ??
  • /**?
  • ?*??
  • ?*?@Description:?顧客?
  • ?*?@author?Somnus?
  • ?*?@date?2016年3月9日?下午7:20:41?
  • ?*?@version?1.0?
  • ?*/??
  • public?class?Customer?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????System.out.println("main?BEGIN");??
  • ????????CakeShop?host?=?new?CakeShop();??
  • ????????Cake?cake1?=?host.request(10,?'A');??
  • ????????Cake?cake2?=?host.request(20,?'B');??
  • ????????Cake?cake3?=?host.request(30,?'C');??
  • ????????System.out.println("main?otherJob?BEGIN");??
  • ????????try?{??
  • ????????????Thread.sleep(2000);??
  • ????????}?catch?(InterruptedException?e)?{??
  • ????????}??
  • ??
  • ????????System.out.println("main?otherJob?END");??
  • ????????System.out.println("cake1?=?"?+?cake1.getCake());??
  • ????????System.out.println("cake2?=?"?+?cake2.getCake());??
  • ????????System.out.println("cake3?=?"?+?cake3.getCake());??
  • ????????System.out.println("main?END");??
  • ??
  • ????}??
  • }??
  • ?

      這里的Customer類就相當于“顧客”,CakeShop就相當于“蛋糕店”,顧客向“蛋糕店”定蛋糕就相當于“發請求request”,返回的數據cake是

    DeliveryOrder的實例,就相當于提貨單,而不是真正的“蛋糕”。在過一段時間后(sleep一段時間后),調用data1.getContent(),也就是拿提貨單獲取

    執行結果。

    ?

      下面來看一下,顧客定蛋糕后,蛋糕店做了什么:

    ?

    [java]?view plaincopy print?
  • package?com.somnus.async;??
  • ??
  • /**?
  • ?*?@Description:?TODO?
  • ?*?@author?Somnus?
  • ?*?@date?2016年3月9日?下午7:21:32?
  • ?*?@version?1.0?
  • ?*/??
  • public?class?CakeShop?{??
  • ??
  • ????public?Data?request(final?int?count,?final?char?c)?{??
  • ??
  • ????????System.out.println("request("?+?count?+?",?"?+?c?+?")?BEGIN");??
  • ????????//?(1)?建立DeliveryOrder的實體??
  • ????????final?DeliveryOrder?order?=?new?DeliveryOrder();??
  • ??????????
  • ????????//?(2)?為了建立RealData的實體,啟動新的線程??
  • ????????new?Thread()?{??
  • ????????????public?void?run()?{??
  • ????????????????//在匿名內部類中使用count、order、c。??
  • ????????????????CakeBaker?cakeBaker?=?new?CakeBaker(count,?c);??
  • ????????????????order.setCakeBaker(cakeBaker);??
  • ????????????}??
  • ????????}.start();??
  • ????????System.out.println("request("?+?count?+?",?"?+?c?+?")?END");??
  • ??????????
  • ????????//?(3)?取回FutureData實體,作為傳回值??
  • ????????return?order;??
  • ??
  • ????}??
  • }??


  • ?

      CakeShop("蛋糕店")在接到請求后,先生成了“提貨單”DeliveryOrder的實例order,然后命令“蛋糕師傅CakeBaker去做蛋糕,CakeBaker相當于起

    個線程去做蛋糕了。然后host返回給顧客的僅僅是“提貨單”future,而不是蛋糕。當蛋糕做好后,蛋糕師傅才能給對應的“提貨單”蛋糕,也就

    是order.setCakeBaker(cakeBaker);。


      下面來看看蛋糕師傅是怎么做蛋糕的:

      建立一個字符串,包含count個c字符,為了表現出犯法需要花費一些時間,使用了sleep。

    ?

    [java]?view plaincopy print?
  • package?com.somnus.async;??
  • ??
  • /**?
  • ?*?@Description:?蛋糕師傅?
  • ?*?@author?Somnus?
  • ?*?@date?2016年3月9日?下午7:22:52?
  • ?*?@version?1.0?
  • ?*/??
  • public?class?CakeBaker?implements?Cake?{??
  • ????private?final?String?cake;??
  • ??
  • ????public?CakeBaker(int?count,?char?c)?{??
  • ????????System.out.println("making?cake("?+?count?+?",?"?+?c?+?")?BEGIN");??
  • ????????char[]?buffer?=?new?char[count];??
  • ????????for?(int?i?=?0;?i?<?count;?i++)?{??
  • ????????????buffer[i]?=?c;??
  • ????????????try?{??
  • ????????????????Thread.sleep(3000);??
  • ????????????}?catch?(InterruptedException?e)?{??
  • ????????????????e.printStackTrace();??
  • ????????????}??
  • ????????}??
  • ????????System.out.println("making?cake("?+?count?+?",?"?+?c?+?")?END");??
  • ????????this.cake?=?new?String(buffer);??
  • ????}??
  • ??
  • ????public?String?getCake()?{??
  • ????????return?cake;??
  • ????}??
  • ??
  • }??


  • ?

      現在來看看“提貨單”order是怎么與蛋糕"cake"對應的:

    [java]?view plaincopy print?
  • package?com.somnus.async;??
  • ??
  • /**?
  • ?*?@Description:?提貨單?
  • ?*?@author?Somnus?
  • ?*?@date?2016年3月9日?下午7:25:06?
  • ?*?@version?1.0?
  • ?*/??
  • public?class?DeliveryOrder?implements?Cake?{??
  • ????private?CakeBaker?cakeBaker?=?null;??
  • ??
  • ????private?boolean?ready?=?false;??
  • ??
  • ????public?synchronized?void?setCakeBaker(CakeBaker?cakeBaker)?{??
  • ????????if?(ready)?{??
  • ????????????return;?//?防止setCakeBaker被調用兩次以上。??
  • ????????}??
  • ????????this.cakeBaker?=?cakeBaker;??
  • ????????this.ready?=?true;??
  • ????????notifyAll();??
  • ????}??
  • ??
  • ????public?synchronized?String?getCake()?{??
  • ????????while?(!ready)?{??
  • ????????????try?{??
  • ????????????????wait();??
  • ????????????}?catch?(InterruptedException?e)?{??
  • ????????????????e.printStackTrace();??
  • ????????????}??
  • ????????}??
  • ????????return?cakeBaker.getCake();??
  • ????}??
  • ??
  • }??

  •   顧客做完自己的事情后,會拿著自己的“提貨單”來取蛋糕:

    [html]?view plaincopy print?
  • System.out.println("cake1?=?"?+?cake1.getCake());??

  •   這時候如果蛋糕沒做好,就只好等了:

    [html]?view plaincopy print?
  • while?(!ready)?{??
  • ????try?{??
  • ????????wait();??
  • ????}?catch?(InterruptedException?e)?{??
  • ????????e.printStackTrace();??
  • ????}??
  • }??

  •   //等做好后才能取到

    [html]?view plaincopy print?
  • return?cakeBaker.getCake();??

  •   程序分析

      對于每個請求,host都會生成一個線程,這個線程負責生成顧客需要的“蛋糕”。在等待一段時間以后,如果蛋糕還沒有做好,顧客還必須等待。

    直到“蛋糕被做好”,也就是


      order.setCakeBaker(cakeBaker);執行以后,顧客才能拿走蛋糕。

      每個線程只是專門負責制作特定顧客所需要的“蛋糕”。也就是顧客A對應著蛋糕師傅A,顧客B對應著蛋糕師傅B。即使顧客B的蛋糕被先做好了,

    顧客A也只能等待蛋糕師傅A把蛋糕做好。換句話說,顧客之間沒有競爭關系。

    ?

      類DeliveryOrder的兩個方法被設置為synchronized,實際上蛋糕師傅A與顧客A之間的互斥關系,也就是顧客A必須等待蛋糕師傅A把蛋糕做好后,

    才能拿走,而與蛋糕師傅B是否做好了蛋糕沒有關系。

    轉載于:https://www.cnblogs.com/tuojunjie/p/6836677.html

    總結

    以上是生活随笔為你收集整理的Java多线程实现异步调用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。