内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

多線程等待喚醒機制之生產(chǎn)消費者模式

上篇樓主說明了多線程中死鎖產(chǎn)生的原因并拋出問題——死鎖的解放方案,那么在本篇文章,樓主將引用一個KFC生產(chǎn)漢堡,顧客購買漢堡的過程來說明死鎖解決方案及多線程的等待喚醒機制。

我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站制作、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、懷仁ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的懷仁網(wǎng)站制作公司

簡單地用一幅圖來說明KFC生產(chǎn)漢堡,顧客來消費的過程:

多線程等待喚醒機制之生產(chǎn)消費者模式

場景分析:

  1. 資源類:Hamburger   

  2. 設(shè)置漢堡數(shù)據(jù):SetThread(生產(chǎn)者)

  3. 獲取漢堡數(shù)據(jù):GetThread(消費者)

  4. 測試類:HamburgerTest

  5. 不同種類的線程(生產(chǎn)者、消費者)針對同一資源(漢堡)的操作

  6. 當漢堡有存貨的時候,漢堡師傅不再生產(chǎn),顧客可消費;反之,漢堡師傅生產(chǎn),顧客不可消費

  7. 是否有線程安全問題?當然。樓主在《線程安全問題》那篇文章給出了判定方式,在該場景全部滿足。

代碼構(gòu)建:類里面的i屬性是樓主為了效果好一些特意加的,與本文要說明的問題無關(guān);

首先是資源類Hamburger.java,樓主這里為了模擬只簡單的構(gòu)造了3個字段,其中flag用來表示資源是否有數(shù)據(jù)。

多線程等待喚醒機制之生產(chǎn)消費者模式

 1 package com.jon.hamburger; 2  3 public class Hamburger { 4     private String name;//漢堡名稱 5     private double price;//漢堡價格 6     private boolean flag;//漢堡是否有數(shù)據(jù)的標志,默認為false,表示沒有數(shù)據(jù) 7     public String getName() { 8         return name; 9     }10     public void setName(String name) {11         this.name = name;12     }13     public double getPrice() {14         return price;15     }16     public void setPrice(double price) {17         this.price = price;18     }19     public boolean isFlag() {20         return flag;21     }22     public void setFlag(boolean flag) {23         this.flag = flag;24     }25     26 }

多線程等待喚醒機制之生產(chǎn)消費者模式

接著是生產(chǎn)者SetThread.java與GetThread.java,都需要實現(xiàn)Runnable接口。場景分析中的第7點已經(jīng)說明,場景存在線程安全的問題,樓主在前篇文章已經(jīng)說明,線程安全的問題可以通過加鎖來進行解決,但是這里涉及到不同種類的線程,所以必須要滿足2點:

  1. 不同種類的線程都要加鎖

  2. 不同種類的線程加的鎖必須是同一把

SetThread.java

多線程等待喚醒機制之生產(chǎn)消費者模式

 1 package com.jon.hamburger; 2  3 public class SetThread implements Runnable { 4     private Hamburger hamburger; 5     private int i; 6  7     public SetThread(Hamburger hamburger) { 8         this.hamburger = hamburger; 9     }10     @Override11     public void run() {12         while (true) {//為了數(shù)據(jù)效果好一些,樓主加入了判斷13             synchronized (hamburger) {14                 if(this.hamburger.isFlag()){//如果有存貨15                     try {16                         hamburger.wait();//線程等待17                     } catch (InterruptedException e) {                        
18                         e.printStackTrace();19                     }20                 }21                 //如果沒有存貨,這模擬生產(chǎn)22                 if (i % 2 == 0) {23                     this.hamburger.setPrice(25.0);24                     this.hamburger.setName("俊鍋的漢堡");25                 } else {26                     this.hamburger.setPrice(26.0);27                     this.hamburger.setName("大俊鍋的漢堡");28                 }29                 this.hamburger.setFlag(true);//生產(chǎn)完成后更改標志30                 hamburger.notify();//喚醒當前等待的線程31                 i++;//只為數(shù)據(jù)效果好一些,無實際意義32             }33 34         }35 36     }37 38 }

多線程等待喚醒機制之生產(chǎn)消費者模式

GetThread.java

多線程等待喚醒機制之生產(chǎn)消費者模式

 1 package com.jon.hamburger; 2  3 public class GetThread implements Runnable { 4  5     private Hamburger hamburger; 6     /** 7      * 為了讓同步鎖使用同一個對象鎖,這里通過構(gòu)造方法進行傳遞 8      * @param hamburger 9      */10     public GetThread(Hamburger hamburger){11         this.hamburger = hamburger;12     }13     @Override14     public void run() {15         while(true){16             synchronized (hamburger) {17                 if(!this.hamburger.isFlag()){//如果沒有存貨,線程等待18                     try {19                         hamburger.wait();20                     } catch (InterruptedException e) {                        
21                         e.printStackTrace();22                     }23                 }24                 //如果有數(shù)據(jù)則進行輸出25                 System.out.println(this.hamburger.getName()+"-----"+this.hamburger.getPrice());26                 this.hamburger.setFlag(false);//更改標志27                 hamburger.notify();//喚醒線程28             }    
29         }        
30         31     }32 33 }

多線程等待喚醒機制之生產(chǎn)消費者模式

   可以看到兩個線程類的run方法中都使用了sysnchronized進行了加鎖,并使用同一個hamburger對象鎖。

再看測試類HamburgerTest.java及輸出:

多線程等待喚醒機制之生產(chǎn)消費者模式

 1 package com.jon.hamburger; 2  3  4  5 public class HamburgerTest { 6  7  8     public static void main(String[] args) { 9         Hamburger hamburger = new Hamburger();10         11         SetThread st = new SetThread(hamburger);//通過構(gòu)造方法傳入共享資源數(shù)據(jù)hamburger12         GetThread gt = new GetThread(hamburger);13         14         Thread td1 = new Thread(st);15         Thread td2 = new Thread(gt);16         17         td1.start();18         td2.start();19 20     }21 22 }

多線程等待喚醒機制之生產(chǎn)消費者模式

測試類中,我們通過構(gòu)造方法給SetThread和GetThread傳入了同一個對象,以保證鎖對象為同一把。

輸出結(jié)果,線程間不相互影響,同時都無NULL------0.0的情況輸出:

多線程等待喚醒機制之生產(chǎn)消費者模式

1 俊鍋的漢堡-----25.02 大俊鍋的漢堡-----26.03 俊鍋的漢堡-----25.04 大俊鍋的漢堡-----26.05 俊鍋的漢堡-----25.06 大俊鍋的漢堡-----26.07 俊鍋的漢堡-----25.08 大俊鍋的漢堡-----26.0

多線程等待喚醒機制之生產(chǎn)消費者模式

代碼分析:

我們假設(shè)線程t2先搶到CPU的執(zhí)行權(quán),那么程序執(zhí)行流程可用下圖表示:

多線程等待喚醒機制之生產(chǎn)消費者模式

根據(jù)程序代碼分析也可見,由于線程之間相互等待產(chǎn)生的死鎖問題也得以解決,解決方案就是通過喚醒。另外,文本樓主還使用了另一種方式,思路也差不多,示例代碼與本文的示例代碼放在一起,已上傳到GitHub。

名稱欄目:多線程等待喚醒機制之生產(chǎn)消費者模式
URL鏈接:http://www.rwnh.cn/article40/ggohho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄網(wǎng)站維護、響應(yīng)式網(wǎng)站標簽優(yōu)化、小程序開發(fā)、用戶體驗

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
隆德县| 常宁市| 都昌县| 广东省| 黄山市| 临泽县| 洞头县| 苏尼特右旗| 克东县| 宾川县| 和林格尔县| 太康县| 衡山县| 兴安县| 舟山市| 宾阳县| 安远县| 武山县| 股票| 乐安县| 青田县| 凤城市| 东源县| 上思县| 含山县| 遵化市| 吴川市| 五寨县| 喀喇| 深圳市| 栾城县| 蒲江县| 墨脱县| 枣阳市| 扶绥县| 怀宁县| 思茅市| 淮滨县| 富锦市| 九江县| 阳江市|