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

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

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

    一個關于Java Thread wait(),notify()的實用例(轉)

    一個Java解決生產者-消費者同步問題的例子,很有參考價值的。 

    Java代碼  
    1. /////  
    2. // ProducerConsumer.java  
    3.   
    4. //  
    5. // 這是個很重要的Thread例子。需要注意的是:  
    6. // wait() 必須在synchronized 函數或者代碼塊里面  
    7. // wait()會讓已經獲得synchronized 函數或者代碼塊控制權的Thread暫時休息,并且喪失控制權  
    8. // 這個時候,由于該線程喪失控制權并且進入等待,其他線程就能取得控制權,并且在適當情況下調用notifyAll()來喚醒wait()的線程。  
    9. // 需要注意的是,被喚醒的線程由于已經喪失了控制權,所以需要等待喚醒它的線程結束操作,從而才能重新獲得控制權。  
    10. //  
    11. // 所以wait()的確是馬上讓當前線程喪失控制權,其他的線程可以乘虛而入。  
    12. //  
    13. // 所以wait()的使用,必須存在2個以上線程,而且必須在不同的條件下喚醒wait()中的線程。  
    14. //  
    15. //  
    16. // 以下的例子:  
    17. // ProductStack 是一個生產者跟消費者共享的同步機制,這個機制決定了什么情況生產者要wait(),什么情況消費者要wait()  
    18. // 可以把ProductStack看作一個產品倉庫。當產品倉庫滿的時候,生產者線程需要wait(),從而放棄對產品倉庫的控制。  
    19. // 這個時候消費者線程就可以進來了而取得倉庫的控制權。一旦消費者消費了產品,那么倉庫就不滿了。  
    20. // 這個時候消費者線程就要notifyAll()生產者線程,讓等待的生產者線程喚醒。  
    21. // 但是生產者被喚醒后不能馬上進行生產,因為它在wait()的時候已經喪失了對倉庫的控制權,所以就需要等待消費者線程結束操作,  
    22. // 才能重新取得倉庫的控制權,再進行生產。  
    23. //  
    24. // 所以特別注意的是,notifyAll()并不是讓當前線程馬上讓出控制權,而只是讓其他wait()當中的線程喚醒而已,  
    25. // 所以對不起,盡管我喚醒你,可你必須還是要等我用完倉庫才能進來。這點必須清楚。  
    26. //  
    27. // 相反,倉庫如果空的時候,消費者線程就會wait(),然后等待生產者線程來生產產品,生產者進程乘虛而入后,讓生產者線程生產產品  
    28. // 并且喚醒消費者線程。這個情況跟上面就類似了。  
    29. //  
    30. ///  
    31.   
    32. public class ProducerConsumer {  
    33.   
    34.       public static void main(String[] args) {  
    35.   
    36.            ProductStack ps = new ProductStack();  
    37.   
    38.            Producer p = new Producer(ps, "生產者1");  
    39.   
    40.            Consumer c = new Consumer(ps, "消費者1");  
    41.   
    42.            new Thread(p).start();  
    43.   
    44.            new Thread(c).start();  
    45.   
    46.       }  
    47.   
    48. }  
    49. class Product {  
    50.   
    51.       int id;  
    52.       private String producedBy = "N/A";  
    53.   
    54.       private String consumedBy = "N/A";  
    55.   
    56.       // 構造函數,指明產品ID以及生產者名字。  
    57.   
    58.       Product(int id, String producedBy) {  
    59.   
    60.            this.id = id;  
    61.   
    62.            this.producedBy = producedBy;  
    63.   
    64.       }  
    65.   
    66.       // 消費,需要指明消費者名字  
    67.   
    68.       public void consume(String consumedBy) {  
    69.   
    70.            this.consumedBy = consumedBy;  
    71.   
    72.       }  
    73.   
    74.       public String toString() {  
    75.   
    76.            return "Product : " + id + ", produced by " + producedBy  
    77.   
    78.                       + ", consumed by " + consumedBy;  
    79.   
    80.       }  
    81.   
    82.       public String getProducedBy() {  
    83.   
    84.            return producedBy;  
    85.   
    86.       }  
    87.   
    88.       public void setProducedBy(String producedBy) {  
    89.   
    90.            this.producedBy = producedBy;  
    91.   
    92.       }  
    93.   
    94.       public String getConsumedBy() {  
    95.   
    96.            return consumedBy;  
    97.   
    98.       }  
    99.   
    100.       public void setConsumedBy(String consumedBy) {  
    101.   
    102.            this.consumedBy = consumedBy;  
    103.   
    104.       }  
    105. }  
    106.   
    107. // 這個class就是倉庫,是生產者跟消費者共同爭奪控制權的同步資源  
    108.   
    109. class ProductStack {  
    110.   
    111.       int index = 0;  
    112.   
    113.       Product[] arrProduct = new Product[6];  
    114.   
    115.       // push使用來讓生產者放置產品的  
    116.   
    117.       public synchronized void push(Product product) {  
    118.   
    119.            // 如果倉庫滿了  
    120.   
    121.            while (index == arrProduct.length) // 這里本來可以用if(),但是如果catch  
    122.   
    123.                                             // exception會出問題,讓滿的index越界  
    124.   
    125.            {  
    126.   
    127.                  try {  
    128.   
    129.                       // here, "this" means the thread that is using "push"  
    130.   
    131.                       // so in this case it's a producer thread instance.  
    132.   
    133.                       // the BIG difference between sleep() and wait() is, once  
    134.   
    135.                       // wait(),  
    136.   
    137.                       // the thread won't have the lock anymore  
    138.   
    139.                       // so when a producer wait() here, it will lost the lock of  
    140.   
    141.                       // "push()"  
    142.   
    143.                       // While sleep() is still keeping this lock  
    144.   
    145.                       // Important: wait() and notify() should be in "synchronized"  
    146.   
    147.                       // block  
    148.   
    149.                       System.out.println(product.getProducedBy() + " is waiting.");  
    150.   
    151.                       // 等待,并且從這里退出push()  
    152.   
    153.                       wait();  
    154.   
    155.                  } catch (InterruptedException e) {  
    156.   
    157.                       e.printStackTrace();  
    158.   
    159.                  }  
    160.   
    161.            }  
    162.   
    163.            System.out.println(product.getProducedBy() + " sent a notifyAll().");  
    164.   
    165.            // 因為我們不確定有沒有線程在wait(),所以我們既然生產了產品,就喚醒有可能等待的消費者,讓他們醒來,準備消費  
    166.   
    167.            notifyAll();  
    168.   
    169.            // 注意,notifyAll()以后,并沒有退出,而是繼續執行直到完成。  
    170.   
    171.            arrProduct[index] = product;  
    172.   
    173.            index++;  
    174.   
    175.            System.out.println(product.getProducedBy() + " 生產了: " + product);  
    176.   
    177.       }  
    178.   
    179.       // pop用來讓消費者取出產品的  
    180.   
    181.       public synchronized Product pop(String consumerName) {  
    182.   
    183.            // 如果倉庫空了  
    184.   
    185.            while (index == 0) {  
    186.   
    187.                  try {  
    188.   
    189.                       // here will be the consumer thread instance will be waiting ,  
    190.   
    191.                       // because empty  
    192.   
    193.                       System.out.println(consumerName + " is waiting.");  
    194.   
    195.                       // 等待,并且從這里退出pop()  
    196.   
    197.                       wait();  
    198.   
    199.                  } catch (InterruptedException e) {  
    200.   
    201.                       e.printStackTrace();  
    202.   
    203.                  }  
    204.   
    205.            }  
    206.   
    207.            System.out.println(consumerName + " sent a notifyAll().");  
    208.   
    209.            // 因為我們不確定有沒有線程在wait(),所以我們既然消費了產品,就喚醒有可能等待的生產者,讓他們醒來,準備生產  
    210.   
    211.            notifyAll();  
    212.   
    213.            // 注意,notifyAll()以后,并沒有退出,而是繼續執行直到完成。  
    214.   
    215.            // 取出產品  
    216.   
    217.            index--;  
    218.   
    219.            Product product = arrProduct[index];  
    220.   
    221.            product.consume(consumerName);  
    222.   
    223.            System.out.println(product.getConsumedBy() + " 消費了: " + product);  
    224.   
    225.            return product;  
    226.   
    227.       }  
    228.   
    229. }  
    230.   
    231. class Producer implements Runnable {  
    232.   
    233.       String name;  
    234.       ProductStack ps = null;  
    235.   
    236.       Producer(ProductStack ps, String name) {  
    237.   
    238.            this.ps = ps;  
    239.   
    240.            this.name = name;  
    241.   
    242.       }  
    243.   
    244.       public void run() {  
    245.   
    246.            for (int i = 0; i < 20; i++) {  
    247.   
    248.                  Product product = new Product(i, name);  
    249.   
    250.                  ps.push(product);  
    251.   
    252.                  try {  
    253.   
    254.                       Thread.sleep((int) (Math.random() * 200));  
    255.   
    256.                  } catch (InterruptedException e) {  
    257.   
    258.                       e.printStackTrace();  
    259.   
    260.                  }  
    261.   
    262.            }  
    263.   
    264.       }  
    265.   
    266. }  
    267.   
    268.   
    269. class Consumer implements Runnable {  
    270.   
    271.       String name;  
    272.       ProductStack ps = null;  
    273.       Consumer(ProductStack ps, String name) {  
    274.   
    275.            this.ps = ps;  
    276.   
    277.            this.name = name;  
    278.   
    279.       }  
    280.   
    281.       public void run() {  
    282.   
    283.            for (int i = 0; i < 20; i++) {  
    284.   
    285.                  Product product = ps.pop(name);  
    286.   
    287.                  try {  
    288.   
    289.                       Thread.sleep((int) (Math.random() * 1000));  
    290.   
    291.                  } catch (InterruptedException e) {  
    292.   
    293.                       e.printStackTrace();  
    294.   
    295.                  }  
    296.   
    297.            }  
    298.   
    299.       }  
    300.   
    301. }  

    posted on 2012-04-17 13:39 AlanLiu 閱讀(654) 評論(0)  編輯  收藏 所屬分類: java


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


    網站導航:
     
    <2012年4月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    293012345

    導航

    統計

    常用鏈接

    留言簿

    隨筆分類

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲一区二区三区无码中文字幕| 24小时日本电影免费看| 免费三级毛片电影片| 亚洲偷自拍另类图片二区| 亚洲精品无码AV中文字幕电影网站| 香蕉成人免费看片视频app下载| 亚洲人成网网址在线看| 亚洲国产精品人人做人人爽 | 亚洲另类自拍丝袜第五页| 亚洲精品NV久久久久久久久久| 95免费观看体验区视频| 久久亚洲私人国产精品vA| 真实乱视频国产免费观看| 日韩亚洲产在线观看| 亚洲熟女乱综合一区二区| 91免费在线播放| 成年免费a级毛片| 亚洲午夜国产片在线观看| 91成人免费在线视频| 精品免费久久久久国产一区 | 欧洲美熟女乱又伦免费视频| 中文字幕看片在线a免费| 亚洲免费综合色在线视频| 亚洲国产精品VA在线看黑人| 国产在线观看免费不卡| 日本高清不卡中文字幕免费| 亚洲国产精品久久网午夜 | 亚洲av无码国产综合专区| 免费无码又爽又刺激高潮的视频| 久久精品国产大片免费观看| 男女猛烈xx00免费视频试看| 亚洲人成7777| 久久精品国产亚洲av麻豆小说| 久久亚洲中文字幕精品一区四| 成人免费视频国产| 一二三四视频在线观看中文版免费| 久久久久久久久久国产精品免费| caoporn成人免费公开| 羞羞视频免费观看| 91在线亚洲综合在线| 亚洲日产2021三区在线|