天天看點

多線程---和尚吃饅頭問題

在項目中,經常用到一種設計模式----單例模式,下面舉一個小案例,說明線程安全的單例模式在多線程中的應用,以供學習參考:

    和尚吃饅頭:

100個饅頭,30個和尚,每個和尚最少吃一個饅頭,最多不超過4個饅頭,保證上述條件的情況下,

盡快将饅頭吃了!

要求是嚴格單例模式實作籃子類(存放饅頭的容器)。

[java] view plain copy print ?

  1. <span style="font-size:18px;">package java.thread;  
  2. public class MantouDemo {  
  3.     public static void main(String[] args) {  
  4.         for(int i = 0 ; i < Box.uneatedMonks ; i ++){  
  5.             new Monk("tom" + i).start();  
  6.         }  
  7.     }  
  8. }  
  9. //籃子  
  10. class Box{  
  11.     private static Box instance = null ;  
  12.     private static Object lock = new Object();  
  13.     //饅頭總數  
  14.     private int COUNT = 100 ;  
  15.     //沒吃饅頭的和尚數量  
  16.     public static int uneatedMonks = 30 ;  
  17.     public static Box getInstance(){  
  18.         if(instance != null){  
  19.             return instance ;  
  20.         }  
  21.         synchronized (lock){  
  22.             if(instance == null){  
  23.                 instance = new Box();  
  24.             }  
  25.             return instance ;  
  26.         }  
  27.     }  
  28.     private Box(){  
  29.     }  
  30.     //擷取饅頭  
  31.     public int getMantou(Monk monk){  
  32.         //1.是否還有可吃饅頭  
  33.         if(COUNT == 0){  
  34.             return 0 ;  
  35.         }  
  36.         //2.和尚是否吃飽了  
  37.         if(monk.getCount() == Monk.MAX){  
  38.             return 0 ;  
  39.         }  
  40.         //3.還有多餘的饅頭  
  41.         if(COUNT > uneatedMonks){  
  42.             int tmp = COUNT ;  
  43.             COUNT -- ;  
  44.             //和尚是否是第一次吃饅頭  
  45.             if(monk.getCount() == 0){  
  46.                 uneatedMonks -- ;  
  47.             }  
  48.             return tmp ;  
  49.         }  
  50.         //沒有多餘的饅頭  
  51.         else{  
  52.             if(monk.getCount() == 0){  
  53.                 int tmp = COUNT;  
  54.                 COUNT--;  
  55.                 uneatedMonks--;  
  56.                 return tmp ;  
  57.             }  
  58.         }  
  59.         return 0 ;  
  60.     }  
  61. }  
  62. //和尚  
  63. class Monk extends Thread{  
  64.     public static int MAX = 4 ;  
  65.     public static int MIN = 1 ;  
  66.     //和尚吃了饅頭的數量  
  67.     private int count = 0 ;  
  68.     public int getCount() {  
  69.         return count;  
  70.     }  
  71.     public void setCount(int count) {  
  72.         this.count = count;  
  73.     }  
  74.     private String monkName ;  
  75.     public Monk(String monkName) {  
  76.         this.monkName = monkName ;  
  77.     }  
  78.     public void run() {  
  79.         Box box = Box.getInstance();  
  80.         while(true){  
  81.             int mantouNo = box.getMantou(this) ;  
  82.             if(mantouNo != 0){  
  83.                 count ++ ;  
  84.             }  
  85.             else{  
  86.                 break ;  
  87.             }  
  88.             yield();  
  89.         }  
  90.         System.out.println(monkName + " : " + count );  
  91.     }  
  92. }  
  93. </span>