1. 程式人生 > >生產者與消費者 程式碼實現 java

生產者與消費者 程式碼實現 java

        首先,我利用忙測試寫出了第一次版本的程式碼

     

  1 package How;
  2 //自寫程式碼  缺陷 無法完全實現pv操作執行緒處於忙測試狀態
  3 public class bin_1_1 
  4 {
  5   
  6     public static void main(String[] args) 
  7     {
  8             Producter  producter;  //生產者執行緒
  9             Consumer   consumer;   //
消費者執行緒 10 Buffer buffer; 11 buffer=new Buffer(10); 12 producter =new Producter(buffer); 13 consumer =new Consumer(buffer); 14 producter.start(); 15 consumer.start(); 16 } 17 18 } 19 class Producter extends
Thread 20 { 21 Buffer buffer; 22 public Producter(Buffer buffer) 23 { 24 this.buffer=buffer; 25 } 26 public void run() 27 { 28 while(true) 29 { 30 31 try 32 { 33 //模擬資料生產時間 34 Thread.sleep((int
)Math.random()*5000+400); 35 IsEmpty(); //p(Empty) 36 //尋找空的快取區 記錄其標號為K 37 int k = 0; 38 for(int i=0; i<buffer.state_of_objs.length; i++) 39 { 40 if(buffer.state_of_objs[i]==0) 41 { 42 k=i; 43 break; 44 } 45 46 } 47 write(k); 48 } 49 catch (InterruptedException e) 50 { 51 52 e.printStackTrace(); 53 } 54 55 } 56 } 57 synchronized public void IsEmpty() throws InterruptedException 58 { 59 60 while(true) 61 { 62 if(buffer.empty==0) 63 { 64 this.sleep(1); 65 } 66 else 67 { 68 buffer.empty--; 69 break; 70 } 71 } 72 } 73 public void write( int k ) //寫入互斥,進位制其他生產者訪問 74 { 75 try 76 { 77 //模擬資料寫入時間 78 Thread.sleep((int)Math.random()*1000+100); 79 //更改狀態 80 System.out.println(Thread.currentThread().getName()+": 寫"+k+"號快取區"); 81 buffer.state_of_objs[k]=1; 82 buffer.full++; 83 } catch (InterruptedException e) 84 { 85 e.printStackTrace(); 86 } 87 } 88 } 89 class Consumer extends Thread 90 { 91 Buffer buffer; 92 public Consumer(Buffer buffer) 93 { 94 this.buffer=buffer; 95 } 96 public void run() 97 { 98 while(true) 99 { 100 try 101 { 102 IsFull(); 103 int k = 0; 104 for(int i=0; i<buffer.state_of_objs.length; i++) 105 { 106 if(buffer.state_of_objs[i]==1) 107 { 108 k=i; 109 break; 110 } 111 } 112 read(k); 113 //模擬消費時間 114 Thread.sleep((int)Math.random()*5000+300); 115 } 116 catch (InterruptedException e) 117 { 118 e.printStackTrace(); 119 } 120 } 121 } 122 synchronized public void IsFull() throws InterruptedException 123 { 124 125 while(true) 126 { 127 if(buffer.full==0) 128 { 129 this.sleep(1); 130 } 131 else 132 { 133 buffer.full--; 134 break; 135 } 136 } 137 } 138 public void read( int k) 139 { 140 try 141 { 142 //模擬讀時間 143 Thread.sleep((int)Math.random()*3000+250); 144 System.out.println(Thread.currentThread().getName()+": 讀"+k+"號快取區"); 145 //更改狀態 146 buffer.state_of_objs[k]=0; 147 buffer.empty++; 148 } catch (InterruptedException e) 149 { 150 e.printStackTrace(); 151 } 152 } 153 } 154 class Buffer //快取區 臨界資源記錄區 155 { 156 int size; //快取區大小 157 Object[] objs; // 158 int full=0; 159 int empty; 160 int []state_of_objs; 161 public Buffer(int size) 162 { 163 this.size=size; 164 this.empty=size; 165 objs =new Object[size]; 166 state_of_objs=new int[size]; 167 for(int i=0; i<size; i++) 168 { 169 state_of_objs[i]=0; 170 } 171 } 172 }

針對上述情況我,參考了一些其他人的程式碼
package How;
//參考程式碼  主要學習執行緒的各種鎖!  
public class bin_1_2 {
    private static Integer count = 0;
    private final Integer  FULL  = 10;
    private static String  LOCK  = "LOCK";

    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (LOCK) {
                    while (count == FULL) {
                        try {
                            LOCK.wait();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    count++;
                    System.out.println(Thread.currentThread().getName() + "生產者生產,目前總共有" + count);
                    LOCK.notifyAll();
                }
            }
        }
    }

    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                synchronized (LOCK) {
                    while (count == 0) {
                        try {
                            LOCK.wait();
                        } catch (Exception e) {
                        }
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName() + "消費者消費,目前總共有" + count);
                    LOCK.notifyAll();
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        bin_1_2 bin_1_2 = new bin_1_2();
        new Thread(bin_1_2.new Producer()).start();
        new Thread(bin_1_2.new Consumer()).start();
        new Thread(bin_1_2.new Producer()).start();
        new Thread(bin_1_2.new Consumer()).start();
        new Thread(bin_1_2.new Producer()).start();
        new Thread(bin_1_2.new Consumer()).start();
        new Thread(bin_1_2.new Producer()).start();
        new Thread(bin_1_2.new Consumer()).start();
    }
}

 

  這個程式碼為 多個消費者,生產者的問題,通過這個程式碼,我瞭解了synchronized使用方式。
package How;
//參考程式碼
import java.util.LinkedList;

public class bin_1_3 {
    private LinkedList<Object> storeHouse = new LinkedList<Object>();
    private int MAX = 10;

    public bin_1_3() 
    {
    }

    public void start() {
        new Producer().start();
        new Comsumer().start();
    }

    class Producer extends Thread {
        public void run() {
            while (true) {
                synchronized (storeHouse) {
                    try {
                        while (storeHouse.size() == MAX) {
                            System.out.println("storeHouse is full , please wait");
                            storeHouse.wait();
                        }
                        Object newOb = new Object();
                        if (storeHouse.add(newOb)) {
                            System.out.println("Producer put a Object to storeHouse");
                            Thread.sleep((long) (Math.random() * 3000));
                            storeHouse.notify();
                        }
                    } catch (InterruptedException ie) {
                        System.out.println("producer is interrupted!");
                    }

                }
            }
        }
    }

    class Comsumer extends Thread {
        public void run() {
            while (true) {
                synchronized (storeHouse) {
                    try {
                        while (storeHouse.size() == 0) {
                            System.out.println("storeHouse is empty , please wait");
                            storeHouse.wait();
                        }
                        storeHouse.removeLast();
                        System.out.println("Comsumer get  a Object from storeHouse");
                        Thread.sleep((long) (Math.random() * 3000));
                        storeHouse.notify();
                    } catch (InterruptedException ie) {
                        System.out.println("Consumer is interrupted");
                    }

                }
            }

        }
    }

    public static void main(String[] args) throws Exception {
        bin_1_3 pc = new bin_1_3();
        pc.start();
    }
}

 

    這個程式碼學習到了 LinkedList這個類庫,從此我便可以快捷的方式實現棧,佇列
最後我的改進程式碼如下: