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

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

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

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

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

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

    import java.util.Random;

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

    }


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

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

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

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

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

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

            System.out.println();
            
    // 消費方法完成,如果存在等待隊列中的線程,應(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個產(chǎn)品
            for(int i=0; i<20; i++{
                
    // 隨機產(chǎn)生一個大寫字母作為產(chǎn)品
                Random r = new Random();
                
    char p = (char)(r.nextInt(26+ 'A');
                
    try {
                    
    // 產(chǎn)品入庫
                    pf.produceProduct(p);
                    
    // 故意sleep,以便消費線程有機會獲得CPU時間片,方便演示
                    Thread.sleep(200);
                }
     catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }

    }


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

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

            }

        }

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

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

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

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

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


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

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

    常用鏈接

    留言簿

    隨筆分類(5)

    隨筆檔案(5)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国内少妇偷人精品视频免费| 成人免费无码大片a毛片软件| 亚洲国产精品成人一区| 亚洲色成人网站WWW永久四虎 | 久久精品无码免费不卡| 亚洲av午夜精品一区二区三区| 人人狠狠综合久久亚洲 | 亚洲色图综合在线| 一区二区三区免费精品视频 | 久久精品国产这里是免费| 国产亚洲综合久久系列| 久久亚洲精品无码gv| 日本一道一区二区免费看| 亚洲毛片在线免费观看| 美女视频黄a视频全免费| 亚洲AV午夜福利精品一区二区 | 国产亚洲av片在线观看18女人 | 永久免费AV无码国产网站| 亚洲中文字幕AV每天更新| 日本不卡视频免费| 丰满妇女做a级毛片免费观看| 中文字幕精品无码亚洲字| 久久久免费的精品| 亚洲人成在线精品| 国产精品视频免费一区二区三区| 亚洲成人在线免费观看| 又黄又爽又成人免费视频| 国产成人va亚洲电影| 成在线人永久免费视频播放| 一级做a爰片久久毛片免费陪 | 国产在线观看免费av站| 亚洲尹人九九大色香蕉网站| 成人无遮挡裸免费视频在线观看 | 亚洲国产天堂久久综合| 亚洲国产成人AV在线播放| 四虎永久在线精品免费观看视频| 亚洲日本一线产区和二线产区对比| 免费在线黄色网址| 99热精品在线免费观看| 亚洲av无码一区二区三区天堂| 激情97综合亚洲色婷婷五|