生产者与消费者问题:
第一步:把架子搭起来
package com.zhj.www;public class ProceduerConsumer {public static void main(String[] args) {}
}//馒头实体
class wotou{int id;wotou(int id) {this.id = id;}public String toString() {return "wotou : "+id;}}
//馒头栈
class syncStack{int index = 0;wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头syncStack(int index) {this.index = index;}//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,public synchronized void push(wotou wt) {arrWT[index] = wt; /*这两行不能分开index++; */}//从里面取馒头,拿最上面的那一个public synchronized wotou pop() {index--;return arrWT[index];}}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{syncStack ss= null;proceduer(syncStack ss) {this.ss = ss;}/*run方法对应着生产过程*/public void run() {for(int i =0;i<20;i++) {wotou wt = new wotou(i);ss.push(wt);}}
}
//消费者
class consumer implements Runnable{syncStack ss= null;consumer(syncStack ss) {this.ss = ss;}public void run() {for(int i =0;i<20;i++) {wotou wotou =ss.pop();System.out.println(wotou);}}
}
第二步:
需要考虑当馒头筐满了怎么办?马上就会报错?在push方法里考虑,让这个线程休息一下;
wait方法来源于object;wait的时候这把锁也就不属于我了。但是sleep的时候我仍然抓住这把锁。
package com.zhj.www;import java.io.IOException;public class ProceduerConsumer {public static void main(String[] args) {syncStack ss = new syncStack();proceduer proceduer = new proceduer(ss);consumer consumer = new consumer(ss);new Thread(proceduer).start();new Thread(consumer).start();}
}//馒头实体
class wotou{int id;wotou(int id) {this.id = id;}public String toString() {return "wotou : "+id;}}
//馒头栈
class syncStack{int index = 0;wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,public synchronized void push(wotou wt) {if(index == arrWT.length){try {this.wait();//当前对象正在执行push方法需要wait}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//哪个线程在等待就唤醒哪个线程arrWT[index] = wt; /*这两行不能分开*/index++; }//从里面取馒头,拿最上面的那一个public synchronized wotou pop() {if(index == 0) {try {this.wait();}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//object类里的方法,唤醒一个;index--;return arrWT[index];}}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{syncStack ss= null;proceduer(syncStack ss) {this.ss = ss;}/*run方法对应着生产过程*/public void run() {for(int i =0;i<20;i++) {wotou wt = new wotou(i);ss.push(wt);System.out.println("生产了:"+wt);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
//消费者
class consumer implements Runnable{syncStack ss= null;consumer(syncStack ss) {this.ss = ss;}public void run() {for(int i =0;i<20;i++) {wotou wotou =ss.pop();System.out.println("消费了:"+wotou);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
运行过程:
可以发现生产一个馒头,就消耗一个馒头。
完善之后的栗子:
package com.zhj.www;import java.io.IOException;public class ProceduerConsumer {public static void main(String[] args) {syncStack ss = new syncStack();proceduer proceduer = new proceduer(ss);consumer consumer = new consumer(ss);new Thread(proceduer).start();new Thread(consumer).start();}
}//馒头实体
class wotou{int id;wotou(int id) {this.id = id;}public String toString() {return "wotou : "+id;}}
//馒头栈
class syncStack{int index = 0;wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,public synchronized void push(wotou wt) {while(index == arrWT.length){try {this.wait();//当前对象正在执行push方法需要wait}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//哪个线程在等待就唤醒哪个线程arrWT[index] = wt; /*这两行不能分开*/index++; }//从里面取馒头,拿最上面的那一个public synchronized wotou pop() {while(index == 0) {try {this.wait();}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//object类里的方法,唤醒一个; index--;return arrWT[index];}}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{syncStack ss= null;proceduer(syncStack ss) {this.ss = ss;}/*run方法对应着生产过程*/public void run() {for(int i =0;i<20;i++) {wotou wt = new wotou(i);ss.push(wt);System.out.println("生产了:"+wt);try {Thread.sleep((int)(Math.random()*200));} catch (InterruptedException e) {e.printStackTrace();}}}
}
//消费者
class consumer implements Runnable{syncStack ss= null;consumer(syncStack ss) {this.ss = ss;}public void run() {for(int i =0;i<20;i++) {wotou wotou =ss.pop();System.out.println("消费了:"+wotou);try {Thread.sleep((int)(Math.random()*1000));} catch (InterruptedException e) {e.printStackTrace();}}}
}
运行之后。