生產者消費者模式程式碼簡單實現
阿新 • • 發佈:2019-02-17
看見有些作者在書上用synchronized同步鎖去實現,利用wait()和notify()發訊號。
其實鎖方法是沒辦法併發的,這樣做會把並行變成序列計算了。
訊號量最好是建立一個新的類包含生產者和消費者的訊號,再使用關鍵字volatile保證有序性。
程式碼如下:
public class Main { public static void main(String[]args){ LinkedList<Integer>queen = new LinkedList<Integer>(); Sign sign = new Sign(); sign.iniSign(); new Thread(new Business(new Productor(),queen,500,100,sign)).start(); new Thread(new Business(new Customer(),queen,5,1000,sign)).start(); } }
/**
* 訊號
*/
public class Sign {
public volatile int sign_p = 0;
public volatile int sing_c = 0;
public void iniSign(){
this.sign_p = 1;
this.sing_c = 0;
}
}
public class Business implements Runnable { Person person; LinkedList<Integer> queen; int len; int time; Sign sign; public Business(Person person,LinkedList<Integer> queen, int len,int time,Sign sign) { this.person = person; this.queen = queen; this.len = len; this.time = time; this.sign = sign; } @Override public void run() { person.doThis(queen,len,time,sign); } }
public interface Person {
void doThis(LinkedList<Integer>queen,int len,int time,Sign sign);
}
/** * 消費者,如果佇列無資料,無法消費 */ public class Customer implements Person { public synchronized void doThis(LinkedList queen, int len, int time, Sign sign) { System.out.println("消費者就緒"); while (true) { while (sign.sing_c == 0) { } try { Thread.sleep(time); } catch (InterruptedException e) { } if (queen.size() > 0) { System.out.println("消費者消費資料: " + queen.removeFirst()); sign.sign_p = 1;//釋放生產訊號 } else { sign.sing_c = 0; //凍結消費訊號 } } } }
public synchronized void doThis(LinkedList<Integer> queen, int len, int time,Sign sign) {
System.out.printf("生產者就緒");
int i = 0;
while (true) {
while(sign.sign_p == 0){
// System.out.println("生產者阻塞!!!");
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
if (queen.size() < len) {
queen.addLast(i);
System.out.println("生產者,生產資料: " + i++);
sign.sing_c = 1;//釋放消費訊號
} else {
sign.sign_p = 0; //凍結生產訊號
}
}
}
}