生產者-消費者(producer-consumer)問題,兩個進程共享一個公共的固定大小的緩沖區。其中一個是生產者,用于將消息放入緩沖區;另外一個是消費者,用于從緩沖區中取出消息。
這樣應該是生產者生產一個產品,然后消費者取走一個產品,然后再生產、再消費,這個看似很理所當然的邏輯在現實中是必然的,但是在程序里卻出現了問題。a:生產者生產了很多消費者卻沒有取,b:生產這還沒有生產完一個完整的產品消費者卻已經取走了好幾次了,這樣取走的產品當然是不合格的。
下面就用生產和消費鞋子為例,看看程序是怎么運行的吧.. .. ..

Demo01
package demo;
class Shoes{
// 鞋子類,兩個屬性:使用者(男/女),大小(大/小)
String user=null;
String size=null;
}
class Pro implements Runnable{
// 生產者,生產
Shoes shoe = null;
public Pro(Shoes s){
this.shoe=s;
}
public void run(){
int i=0;
while(true){
if(i==0){
// 男人穿的鞋子是大號的
shoe.user="男式";
shoe.size="大號";
i=1;
}else{
// 女人穿的鞋子是小號的
shoe.user="女式";
shoe.size="小號";
i=0;
}
}
}
}
class Cus implements Runnable{
Shoes shoe=null;
public Cus(Shoes s){
this.shoe=s;
}
public void run(){
while(true){
System.out.println(shoe.user+"-->"+shoe.size);
}
}
}
public class Demo01 {
/**生產者-消費者問題 producer-consumer
* @param args
*/
public static void main(String[] args) {
// 設置鞋子的一個生產者和一個消費者,并啟動兩個線程,分別進行生產和消費
Shoes shoe = new Shoes();
Pro p = new Pro(shoe);
Cus c = new Cus(shoe);
new Thread(p).start();
new Thread(c).start();
}
}
結果:
從結果中可以看到,第一次取時已經生產完一雙男鞋,女鞋還沒有生產完就取走了女鞋,第二次到第四次消費都是男鞋,看來是要么生產的太多了,沒有取走,要么就是取的太快,只生產了一雙男鞋卻取了四次。
這樣的程序顯然是不符合實際的,所以就要加以改進。
應該是生產時,生產者進入車間并把車間的門上鎖,生產一雙后生產者出來,消費者進入到車間并把車間門上鎖,取到鞋子后出來,這樣車間里只有一個人,要么生產者要么消費者,這樣就可以保證生產合格的產品。
改進的程序:

Demo02
package demo2;
class Shoes{
// 鞋子類,兩個屬性:使用者(男/女),大小(大/小)
String user=null;
String size=null;
private boolean flag = true;
public synchronized void set(String user,String size){
//如果flag的值不是true則要等待
if (!flag){
//等待
try{
wait();
}catch(Exception e){}
}
try{
Thread.sleep(100);
}catch (Exception e){}
// 如果向下繼續執行了,則表示可以設置,flag = true
this.user = user;
this.size = size;
// 修改設置的標志
flag = false;
//喚醒其他線程
notify();
}
//設置一個輸出方法
public synchronized void get(){
// 如果flag的值為true的時候,表示要等待
if(flag){
try{
wait();
}catch(Exception e){}
}
try{
Thread.sleep(100);
}catch (Exception e){}
//如果向下執行了,則表示允許取出
System.out.println(this.user+" --> "+this.size);
//改變標志,表示可以生產了
flag = true;
notify();
}
}
class Pro implements Runnable{
// 生產者,生產
Shoes shoe = null;
public Pro(Shoes s){
this.shoe=s;
}
public void run(){
int i=0;
while(true){
if(i==0){
// 男人穿的鞋子是大號的
shoe.set("男式", "大號");
i=1;
}else{
// 女人穿的鞋子是小號的
shoe.set("女式", "小號");
i=0;
}
}
}
}
class Cus implements Runnable{
Shoes shoe=null;
public Cus(Shoes s){
this.shoe = s;
}
public void run(){
while(true){
shoe.get();
}
}
}
public class Demo02 {
/**生產者-消費者問題 producer-consumer
* @param args
*/
public static void main(String[] args) {
// 設置鞋子的一個生產者和一個消費者,并啟動兩個線程,分別進行生產和消費
Shoes shoe = new Shoes();
Pro p = new Pro(shoe);
Cus c = new Cus(shoe);
new Thread(p).start();
new Thread(c).start();
}
}
運行結果:

posted on 2010-11-12 23:30
Mineralwasser 閱讀(252)
評論(0) 編輯 收藏