生产者与消费者问题:
第一步:把架子搭起来
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();
}
}
}
}
运行之后。