<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Liver's Java
    我不夠貪心!其實(shí)我應(yīng)該明白,心有多貪,舞臺(tái)就會(huì)有多大!堅(jiān)持!奮斗!
    posts - 4,  comments - 6,  trackbacks - 0
    昨天提到了線程,那么就不得不提到“生產(chǎn)者與消費(fèi)者”這樣一個(gè)經(jīng)典的線程同步問題

    場(chǎng)景描述:
        一個(gè)倉(cāng)庫(kù),生產(chǎn)者在工廠里生產(chǎn)了產(chǎn)品后,將產(chǎn)品存放到倉(cāng)庫(kù)里,倉(cāng)庫(kù)存放數(shù)量有限,當(dāng)滿倉(cāng)后,停止生產(chǎn),直到有消費(fèi)著將產(chǎn)品消費(fèi)后才繼續(xù)生產(chǎn);消費(fèi)者從倉(cāng)庫(kù)里提取產(chǎn)品,當(dāng)倉(cāng)庫(kù)空倉(cāng)時(shí),停止消費(fèi)產(chǎn)品,直到倉(cāng)庫(kù)中有產(chǎn)品時(shí),才繼續(xù)消費(fèi)產(chǎn)品。

    代碼的實(shí)現(xiàn)(調(diào)整線程sleep時(shí)間可以實(shí)現(xiàn)生產(chǎn)速度與消費(fèi)速度的不同):
    TestProduceAndConsumer.java
    package com.nantian;

    import java.util.Random;

    public class TestProduceAndConsumer {
        
    public static void main(String[] args) {
            
    // 創(chuàng)建一個(gè)工廠對(duì)象
            ProductFactory pf = new ProductFactory();
            
    // 創(chuàng)建一個(gè)生產(chǎn)者和一個(gè)消費(fèi)者,傳遞工廠的引用,保證兩者操作的是同一個(gè)工廠
            Producer p = new Producer(pf);
            Consumer c 
    = new Consumer(pf);
            
    // 啟動(dòng)兩個(gè)線程
            p.start();
            c.start();
        }

    }


    // 產(chǎn)品工廠
    class ProductFactory {
        
    // product表示倉(cāng)庫(kù)
        private char[] product = ' '' '' '' '' '};
        
    // flag標(biāo)記產(chǎn)品數(shù)量
        private int flag = 0;

        
    // 生產(chǎn)產(chǎn)品
        public synchronized void produceProduct(char p) throws InterruptedException {
            
    // 判斷產(chǎn)品是否滿倉(cāng),以便決定是否繼續(xù)生產(chǎn)
            if (flag == product.length) {
                
    this.wait();
            }

            
    // 當(dāng)代碼執(zhí)行到這里,一定不是滿倉(cāng)狀態(tài)
            product[flag++= p;
            
    // 查看此時(shí)倉(cāng)庫(kù)狀態(tài)(這里不屬于業(yè)務(wù)邏輯部分)
            System.out.print(p + "被生產(chǎn),當(dāng)前倉(cāng)庫(kù)狀態(tài):");
            
    for (char tmp : product) {
                System.out.print(tmp);
            }

            System.out.println();
            
    // 生產(chǎn)方法完成,如果存在等待隊(duì)列中的線程,應(yīng)該喚醒
            this.notifyAll();
        }

        
        
    // 消費(fèi)產(chǎn)品
        public synchronized char consumeProduct() throws InterruptedException {
            
    // 判斷倉(cāng)庫(kù)是否空倉(cāng),以便決定是否消費(fèi)產(chǎn)品
            if(flag == 0{
                
    this.wait();
            }

            
    // 當(dāng)代碼執(zhí)行到這里,一定不是空倉(cāng)狀態(tài)
            char p = product[--flag]; product[flag]=' ';
            
    // 查看此時(shí)倉(cāng)庫(kù)狀態(tài)(這里不屬于業(yè)務(wù)邏輯部分)
            System.out.print(p + "被消費(fèi),當(dāng)前倉(cāng)庫(kù)狀態(tài):");
            
    for(char tmp : product) {
                System.out.print(tmp);
            }

            System.out.println();
            
    // 消費(fèi)方法完成,如果存在等待隊(duì)列中的線程,應(yīng)該喚醒
            this.notifyAll();
            
    return p;
        }

    }


    // 生產(chǎn)者
    class Producer extends Thread {
        
    private ProductFactory pf = null;
        
        
    public Producer(ProductFactory pf) {
            
    this.pf = pf;
        }

        
        
    public void run() {
            
    // 一共生產(chǎn)20個(gè)產(chǎn)品
            for(int i=0; i<20; i++{
                
    // 隨機(jī)產(chǎn)生一個(gè)大寫字母作為產(chǎn)品
                Random r = new Random();
                
    char p = (char)(r.nextInt(26+ 'A');
                
    try {
                    
    // 產(chǎn)品入庫(kù)
                    pf.produceProduct(p);
                    
    // 故意sleep,以便消費(fèi)線程有機(jī)會(huì)獲得CPU時(shí)間片,方便演示
                    Thread.sleep(200);
                }
     catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }

    }


    // 消費(fèi)者
    class Consumer extends Thread {
        
    private ProductFactory pf = null;
        
        
    public Consumer(ProductFactory pf) {
            
    this.pf = pf;
        }

        
        
    public void run() {
            
    // 一共消費(fèi)20個(gè)產(chǎn)品
            for(int i=0; i<20; i++{
                
    try {
                    
    // 產(chǎn)品出庫(kù)
                    pf.consumeProduct();
                    
    // 故意sleep,以便生產(chǎn)線程有機(jī)會(huì)獲得CPU時(shí)間片,方便演示
                    
    // sleep時(shí)間稍微錯(cuò)開,阻止同時(shí)競(jìng)爭(zhēng)CPU時(shí)間片
                    Thread.sleep(300);
                }
     catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }

    }
    posted on 2009-06-04 10:57 Liver 閱讀(1426) 評(píng)論(4)  編輯  收藏 所屬分類: CoreJava

    FeedBack:
    # re: 再談線程:生產(chǎn)者與消費(fèi)者
    2009-06-04 16:22 | wuzhongxing
    利用jdk1.5的concurrent包里面的blockqueue,實(shí)現(xiàn)這種模式還是比較簡(jiǎn)單的  回復(fù)  更多評(píng)論
      
    # re: 再談線程:生產(chǎn)者與消費(fèi)者
    2009-06-04 18:10 | 樂蜂
    實(shí)現(xiàn)這種模式還是比較簡(jiǎn)單的  回復(fù)  更多評(píng)論
      
    # re: 再談線程:生產(chǎn)者與消費(fèi)者[未登錄]
    2009-06-06 16:57 | charlee
    // 判斷產(chǎn)品是否滿倉(cāng),以便決定是否繼續(xù)生產(chǎn)
    if (flag == product.length) {
    this.wait();
    }

    // 判斷倉(cāng)庫(kù)是否空倉(cāng),以便決定是否消費(fèi)產(chǎn)品
    if(flag == 0) {
    this.wait();
    }

    為什么要用if呢?你不覺得while更好么?  回復(fù)  更多評(píng)論
      
    # re: 再談線程:生產(chǎn)者與消費(fèi)者
    2009-06-15 15:53 | 分享愛的空間
    言簡(jiǎn)意賅,不錯(cuò)。。。。
    希望看到更加深入的。  回復(fù)  更多評(píng)論
      

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    <2009年6月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

    常用鏈接

    留言簿

    隨筆分類(5)

    隨筆檔案(5)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 免费无码又爽又刺激一高潮| 本免费AV无码专区一区| 国产成人亚洲午夜电影| 又硬又粗又长又爽免费看| 99免费精品视频| 亚洲最大免费视频网| 日韩精品无码区免费专区| 免费v片在线观看| 亚洲色婷婷六月亚洲婷婷6月| 亚洲黄色片免费看| 亚洲欧美日韩中文二区| 高清免费久久午夜精品| 蜜桃成人无码区免费视频网站 | 亚洲Av永久无码精品黑人| 黄床大片30分钟免费看| 鲁丝片一区二区三区免费| 免费看成人AA片无码视频羞羞网| 国产美女精品久久久久久久免费 | 久久综合亚洲鲁鲁五月天| 亚洲欧洲日产国产最新| 特黄特色大片免费| 无码精品一区二区三区免费视频 | 区三区激情福利综合中文字幕在线一区亚洲视频1 | 最近2022中文字幕免费视频| 毛片a级毛片免费播放下载| www亚洲精品少妇裸乳一区二区 | 亚洲日韩中文无码久久| 亚洲国产精品成人综合色在线婷婷| 亚洲欧美熟妇综合久久久久| 国产免费网站看v片在线| 中文字幕无码视频手机免费看| 亚洲国产成人精品91久久久 | 亚洲AV无码不卡无码| 亚洲女子高潮不断爆白浆| 一个人看的www免费视频在线观看| 日本XXX黄区免费看| 亚洲一区二区视频在线观看| 亚洲国产成人va在线观看网址| 一级成人a免费视频| 免费无码黄十八禁网站在线观看| 国产偷国产偷亚洲清高动态图|