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

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

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

    Liver's Java
    我不夠貪心!其實我應該明白,心有多貪,舞臺就會有多大!堅持!奮斗!
    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è)務邏輯部分)
            System.out.print(p + "被生產(chǎn),當前倉庫狀態(tài):");
            
    for (char tmp : product) {
                System.out.print(tmp);
            }

            System.out.println();
            
    // 生產(chǎn)方法完成,如果存在等待隊列中的線程,應該喚醒
            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è)務邏輯部分)
            System.out.print(p + "被消費,當前倉庫狀態(tài):");
            
    for(char tmp : product) {
                System.out.print(tmp);
            }

            System.out.println();
            
    // 消費方法完成,如果存在等待隊列中的線程,應該喚醒
            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)這種模式還是比較簡單的  回復  更多評論
      
    # re: 再談線程:生產(chǎn)者與消費者
    2009-06-04 18:10 | 樂蜂
    實現(xiàn)這種模式還是比較簡單的  回復  更多評論
      
    # 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更好么?  回復  更多評論
      
    # re: 再談線程:生產(chǎn)者與消費者
    2009-06-15 15:53 | 分享愛的空間
    言簡意賅,不錯。。。。
    希望看到更加深入的。  回復  更多評論
      

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


    網(wǎng)站導航:
     

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

    常用鏈接

    留言簿

    隨筆分類(5)

    隨筆檔案(5)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲AV无码一区二区二三区入口| 中文字幕亚洲激情| 亚洲成人免费在线观看| 日本免费久久久久久久网站| 亚洲精品无码久久久久去q| 国产三级在线免费| 在线免费观看亚洲| 亚洲综合无码一区二区三区| 久久久久久久久无码精品亚洲日韩| a毛片成人免费全部播放| 99爱免费观看视频在线| 亚洲国产精品国自产电影| 国产精品亚洲色婷婷99久久精品| 国产午夜成人免费看片无遮挡| 免费可以在线看A∨网站| 亚洲色精品三区二区一区| 国产免费牲交视频| 午夜免费国产体验区免费的| 中文字幕无码免费久久99| 亚洲 欧洲 视频 伦小说| 国产又粗又长又硬免费视频| 亚洲乱码一二三四区国产| 最近中文字幕mv免费高清视频7| 亚洲第一成年人网站| 性生交片免费无码看人| 国产成人不卡亚洲精品91| 亚洲人成人77777网站| 免费一级特黄特色大片| 亚洲国产精品久久久天堂| 国产免费一级高清淫曰本片| 亚洲Av无码精品色午夜| 永久免费AV无码国产网站| 美女又黄又免费的视频| 国产精品美女自在线观看免费| 一级毛片a女人刺激视频免费| 免费人成激情视频| MM1313亚洲精品无码久久| 亚洲精品白浆高清久久久久久| 午夜性色一区二区三区免费不卡视频 | 国精无码欧精品亚洲一区| 18国产精品白浆在线观看免费 |