解决方案 »
- 请教一个问题,JAVA调用DLL时参数传递的问题
- 【JAVA】用bin.readLine()输入数据后用bw.write()写入文本后显示的却是ASCII码,怎么办?
- 用星号导入类的问题。
- 为什么我安装了jdk1.5+netbeans6.1后,netbeans服务视图中没有服务器?
- java怎样调用系统命令
- 关于className及调用其方法的问题。有点晕了
- 如何建立一个圆形按钮,当单击它时,在右边的PANEL中画出一个圆,并且这个圆可以移动和改变大小?
- insert语句可否使其中一字段与ID号同步?
- 啥时候才会加载<JAVA_HOME> jre\lib\ext 目录下的jar包
- Java中一个比较费解的问题?
- 一道关于计算的题,请教下!!
- RMI问题小问
public static void main(String[] args) {
Basket basket = new Basket();
Producer producer = new Producer(basket);
Consumer consumer = new Consumer(basket);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
}
}class Bread {
private String producer; Bread(String producer) {
this.producer = producer;
} public String toString() {
return producer;
}
}class Basket {
private int index = 0;
Bread[] bread = new Bread[6]; public synchronized void push(Bread b) {
System.out.println("生产前篮子里面包数:" + index);
while (index == bread.length) {
System.out.println("篮子里满了,开始等待!");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bread[index] = b;
index++;
this.notify();
} public synchronized Bread pop() {
System.out.println("消费前篮子里面包数为:" + index);
while (index == 0) {
System.out.println("篮子里为空,开始等待!");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
index--;
this.notify();
return bread[index];
}
}class Producer implements Runnable {
private Basket basket; public Producer(Basket basket) {
this.basket = basket;
} public void run() {
for (int i = 0; i < 10; i++) {
Bread bread = new Bread("第" + i + "个面包");
basket.push(bread);
System.out.println("生产了: " + bread);
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
} }
}class Consumer implements Runnable {
private Basket basket; public Consumer(Basket basket) {
this.basket = basket;
} public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("消费了:" + basket.pop());
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}
假设生产者生产满了篮子,然后就会处于休眠转台,消费者一直在篮子里取面包,等到面包完了以后就处于休眠状态。这时候就是消费者和生产者都处于休眠状态,这个生产消费者系统将不会继续用作。所以要保证系统的正常运行,至少应该在消费者消费完篮子里面的东西时,自我休眠前唤醒生产者来工作。
修改后:
生产者:Thread.sleep(100);
消费者:
//假设消费者来的时间间隔最小为1,最大为1000,产生随机数
//取当前时间的毫秒,取模
long lTime=System.currentTimeMillis();
lTime=lTime/1000 + 1;
Thread.sleep(lTime); 修改后运行结果:
run:
生产前篮子里面包数:0
生产了: 第0个面包
消费前篮子里面包数为:1
消费了:第0个面包
生产前篮子里面包数:0
生产了: 第1个面包
生产前篮子里面包数:1
生产了: 第2个面包
生产前篮子里面包数:2
生产了: 第3个面包
生产前篮子里面包数:3
生产了: 第4个面包
生产前篮子里面包数:4
生产了: 第5个面包
生产前篮子里面包数:5
生产了: 第6个面包
生产前篮子里面包数:6
篮子里满了,开始等待!
加上4楼的互相唤醒机制,就ok了........
重新修改了程序package test;import java.util.ArrayList;
import java.util.List;public class ProducerConsumer { private Basket basket=new Basket(); public void begin() {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
} class Bread { private String producer; Bread(String producer) {
this.producer = producer;
} @Override
public String toString() {
return producer;
}
} class Custom { private String custom; Custom(String custom) {
this.custom = custom;
} @Override
public String toString() {
return custom;
}
} class Basket { List<Bread> breadList = new ArrayList<Bread>(); public void push(Bread b) { if (breadList.size() > 5) {
System.out.println("篮子里满了,请等待!");
} else {
breadList.add(b);
System.out.println("生产后篮子里面包数:" + breadList.size());
}
} public Bread pop() {
Bread bread = null;
if (breadList.size() == 0) {
System.out.println("篮子里为空,请等待!");
} else {
bread = breadList.get(0);
breadList.remove(0);
System.out.println("消费后篮子里面包数为:" + breadList.size());
}
return bread;
}
} class Producer implements Runnable { public Producer() {
} public void run() {
for (int i = 0; i < 100; i++) {
while (basket.breadList.size() > 5) {
try {
//如果篮子满了等待时间
System.out.println("篮子里满了,生产开始等待!");
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Bread bread = new Bread("第" + i + "个面包");
basket.push(bread);
System.out.println("生产了: " + bread);
try {
//生产面包所需时间
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} class Consumer implements Runnable { public Consumer() {
} public void run() {
for (int i = 0; i < 100; i++) {
while (basket.breadList.size() == 0) {
try {
//如果篮子空了等待时间
System.out.println("篮子里空了,消费者开始等待!");
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费了:" + basket.pop());
try {
//假设消费者来的时间间隔最小为1,最大为200,产生随机数
//取当前时间的毫秒,取模
long lTime = System.currentTimeMillis();
lTime = lTime % 300 + 1;
Thread.sleep(lTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
程序main类:package test;public class Main { /**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
ProducerConsumer producer= new ProducerConsumer();
producer.begin();
}}
调整不同的生产时间和消费者产生时间,会看到生产者等待和消费者等待的不同情况。
运行结果:
run:
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第0个面包
消费后篮子里面包数为:0
消费了:第0个面包
生产后篮子里面包数:1
生产了: 第1个面包
消费后篮子里面包数为:0
消费了:第1个面包
生产后篮子里面包数:1
生产了: 第2个面包
消费后篮子里面包数为:0
消费了:第2个面包
生产后篮子里面包数:1
生产了: 第3个面包
消费后篮子里面包数为:0
消费了:第3个面包
生产后篮子里面包数:1
生产了: 第4个面包
消费后篮子里面包数为:0
消费了:第4个面包
生产后篮子里面包数:1
生产了: 第5个面包
消费后篮子里面包数为:0
消费了:第5个面包
生产后篮子里面包数:1
生产了: 第6个面包
消费后篮子里面包数为:0
消费了:第6个面包
生产后篮子里面包数:1
生产了: 第7个面包
消费后篮子里面包数为:0
消费了:第7个面包
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第8个面包
消费后篮子里面包数为:0
消费了:第8个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第9个面包
消费后篮子里面包数为:0
消费了:第9个面包
生产后篮子里面包数:1
生产了: 第10个面包
消费后篮子里面包数为:0
消费了:第10个面包
生产后篮子里面包数:1
生产了: 第11个面包
消费后篮子里面包数为:0
消费了:第11个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第12个面包
消费后篮子里面包数为:0
消费了:第12个面包
生产后篮子里面包数:1
生产了: 第13个面包
消费后篮子里面包数为:0
消费了:第13个面包
生产后篮子里面包数:1
生产了: 第14个面包
生产后篮子里面包数:2
生产了: 第15个面包
消费后篮子里面包数为:1
消费了:第14个面包
生产后篮子里面包数:2
生产了: 第16个面包
消费后篮子里面包数为:1
消费了:第15个面包
消费后篮子里面包数为:0
消费了:第16个面包
生产后篮子里面包数:1
生产了: 第17个面包
生产后篮子里面包数:2
生产了: 第18个面包
消费后篮子里面包数为:1
消费了:第17个面包
生产后篮子里面包数:2
生产了: 第19个面包
消费后篮子里面包数为:1
消费了:第18个面包
消费后篮子里面包数为:0
消费了:第19个面包
生产后篮子里面包数:1
生产了: 第20个面包
消费后篮子里面包数为:0
消费了:第20个面包
生产后篮子里面包数:1
生产了: 第21个面包
消费后篮子里面包数为:0
消费了:第21个面包
生产后篮子里面包数:1
生产了: 第22个面包
消费后篮子里面包数为:0
消费了:第22个面包
生产后篮子里面包数:1
生产了: 第23个面包
消费后篮子里面包数为:0
消费了:第23个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第24个面包
消费后篮子里面包数为:0
消费了:第24个面包
生产后篮子里面包数:1
生产了: 第25个面包
消费后篮子里面包数为:0
消费了:第25个面包
生产后篮子里面包数:1
生产了: 第26个面包
消费后篮子里面包数为:0
消费了:第26个面包
生产后篮子里面包数:1
生产了: 第27个面包
生产后篮子里面包数:2
生产了: 第28个面包
消费后篮子里面包数为:1
消费了:第27个面包
消费后篮子里面包数为:0
消费了:第28个面包
生产后篮子里面包数:1
生产了: 第29个面包
消费后篮子里面包数为:0
消费了:第29个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第30个面包
消费后篮子里面包数为:0
消费了:第30个面包
生产后篮子里面包数:1
生产了: 第31个面包
消费后篮子里面包数为:0
消费了:第31个面包
生产后篮子里面包数:1
生产了: 第32个面包
消费后篮子里面包数为:0
消费了:第32个面包
生产后篮子里面包数:1
生产了: 第33个面包
消费后篮子里面包数为:0
消费了:第33个面包
生产后篮子里面包数:1
生产了: 第34个面包
消费后篮子里面包数为:0
消费了:第34个面包
生产后篮子里面包数:1
生产了: 第35个面包
消费后篮子里面包数为:0
消费了:第35个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第36个面包
消费后篮子里面包数为:0
消费了:第36个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第37个面包
消费后篮子里面包数为:0
消费了:第37个面包
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第38个面包
消费后篮子里面包数为:0
消费了:第38个面包
篮子里空了,消费者开始等待!
生产后篮子里面包数:1
生产了: 第39个面包
消费后篮子里面包数为:0
消费了:第39个面包
篮子里空了,消费者开始等待!
篮子里空了,消费者开始等待!
import java.util.List;/**
*
* @author pantianzhu
*/
public class ProducerConsumer { private Basket basket=new Basket(); public void begin() {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
Thread thread3 = new Thread(basket);
thread1.start();
thread2.start();
thread3.run();
} class Bread { private String producer; Bread(String producer) {
this.producer = producer;
} @Override
public String toString() {
return producer;
}
} class Custom { private String custom;
private int breads; Custom(String custom,int breads) {
this.custom = custom;
this.breads = breads;
} @Override
public String toString() {
return custom;
}
} class Basket implements Runnable { List<Bread> breadList = new ArrayList<Bread>();
List<Custom> custList = new ArrayList<Custom>(); public void push(Bread b) { if (breadList.size() > 5) {
System.out.println("篮子里满了,请等待!");
} else {
breadList.add(b);
System.out.println("生产后篮子里面包数:" + breadList.size());
}
} public Bread pop() {
Bread bread = null;
if (breadList.size() == 0) {
System.out.println("篮子里为空,请等待!");
} else {
bread = breadList.get(0);
breadList.remove(0);
// System.out.println("消费后篮子里面包数为:" + breadList.size()+",排队的客户数"+custList.size());
}
return bread;
} public void run() {
while(true){
if(custList.size()>0){
Custom custom=custList.get(0);
for(int i=0;i<custom.breads;i++){
boolean succ=false;
while(!succ){
Bread bread = pop();
if (bread != null) {
System.out.println(custList.get(0) + "消费了" + bread.toString());
succ=true;
}else{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
custList.remove(0);
System.out.println("消费后篮子里面包数为:" + breadList.size()+",排队的客户数"+custList.size());
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} class Producer implements Runnable { public Producer() {
} public void run() {
for (int i = 0; i < 100; i++) {
while (basket.breadList.size() > 5) {
try {
//如果篮子满了等待时间
System.out.println("篮子里满了,生产开始等待!");
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Bread bread = new Bread("第" + i + "个面包");
basket.push(bread);
System.out.println("生产了: " + bread);
try {
//生产面包所需时间
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} class Consumer implements Runnable { public Consumer() {
} public void run() {
for (int i = 0; i < 20; i++) {
long lbuys;
int buys=0;
//假设消费者购买数最小为1,最大为3,产生随机数
//取当前时间的毫秒,取模
lbuys = System.currentTimeMillis();
buys = (int)(lbuys % 3) + 1;
Custom custom = new Custom("第" + i + "个客户",buys);
basket.custList.add(custom);
System.out.println("产生了" +custom.toString()+",要购买"+custom.breads+"个面包");
try {
//假设消费者来的时间间隔最小为1,最大为200,产生随机数
//取当前时间的毫秒,取模
long lTime = System.currentTimeMillis();
lTime = lTime % 400 + 1;
Thread.sleep(lTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}run:
产生了第0个客户,要购买2个面包
生产后篮子里面包数:1
生产了: 第0个面包
第0个客户消费了第0个面包
篮子里为空,请等待!
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第1个面包
第0个客户消费了第1个面包
消费后篮子里面包数为:0,排队的客户数0
生产后篮子里面包数:1
生产了: 第2个面包
产生了第1个客户,要购买2个面包
第1个客户消费了第2个面包
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第3个面包
第1个客户消费了第3个面包
消费后篮子里面包数为:0,排队的客户数0
生产后篮子里面包数:1
生产了: 第4个面包
产生了第2个客户,要购买3个面包
第2个客户消费了第4个面包
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第5个面包
第2个客户消费了第5个面包
篮子里为空,请等待!
产生了第3个客户,要购买1个面包
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第6个面包
第2个客户消费了第6个面包
消费后篮子里面包数为:0,排队的客户数1
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第7个面包
第3个客户消费了第7个面包
消费后篮子里面包数为:0,排队的客户数0
产生了第4个客户,要购买3个面包
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第8个面包
第4个客户消费了第8个面包
篮子里为空,请等待!
篮子里为空,请等待!
篮子里为空,请等待!
产生了第5个客户,要购买3个面包
产生了第6个客户,要购买2个面包
生产后篮子里面包数:1
生产了: 第9个面包
第4个客户消费了第9个面包
篮子里为空,请等待!
篮子里为空,请等待!
产生了第7个客户,要购买1个面包
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第10个面包
第4个客户消费了第10个面包
消费后篮子里面包数为:0,排队的客户数3
产生了第8个客户,要购买2个面包
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第11个面包
第5个客户消费了第11个面包
篮子里为空,请等待!
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第12个面包
第5个客户消费了第12个面包
篮子里为空,请等待!
篮子里为空,请等待!
篮子里为空,请等待!
产生了第9个客户,要购买1个面包
生产后篮子里面包数:1
生产了: 第13个面包
第5个客户消费了第13个面包
消费后篮子里面包数为:0,排队的客户数4
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第14个面包
第6个客户消费了第14个面包
篮子里为空,请等待!
产生了第10个客户,要购买3个面包
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第15个面包
第6个客户消费了第15个面包
消费后篮子里面包数为:0,排队的客户数4
产生了第11个客户,要购买3个面包
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第16个面包
第7个客户消费了第16个面包
消费后篮子里面包数为:0,排队的客户数4
篮子里为空,请等待!
产生了第12个客户,要购买3个面包
篮子里为空,请等待!
产生了第13个客户,要购买2个面包
生产后篮子里面包数:1
生产了: 第17个面包
第8个客户消费了第17个面包
篮子里为空,请等待!
产生了第14个客户,要购买3个面包
篮子里为空,请等待!
篮子里为空,请等待!
产生了第15个客户,要购买1个面包
生产后篮子里面包数:1
生产了: 第18个面包
第8个客户消费了第18个面包
消费后篮子里面包数为:0,排队的客户数7
篮子里为空,请等待!
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第19个面包
第9个客户消费了第19个面包
消费后篮子里面包数为:0,排队的客户数6
产生了第16个客户,要购买1个面包
篮子里为空,请等待!
产生了第17个客户,要购买3个面包
篮子里为空,请等待!
产生了第18个客户,要购买1个面包
生产后篮子里面包数:1
生产了: 第20个面包
第10个客户消费了第20个面包
篮子里为空,请等待!
篮子里为空,请等待!
产生了第19个客户,要购买3个面包
篮子里为空,请等待!
生产后篮子里面包数:1
生产了: 第21个面包
第10个客户消费了第21个面包
篮子里为空,请等待!
篮子里为空,请等待!
public static void main(String[] args) {
Basket basket = new Basket();
Producer producer = new Producer(basket);
Consumer consumer = new Consumer(basket);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
}
}class Bread {
private String producer;
Bread(String producer) {
this.producer = producer;
}
public String toString() {
return producer;
}
}class Basket {
private int index = 0;
Bread[] bread = new Bread[6];
public synchronized void push(Bread b) {
System.out.println("生产前篮子里面包数:" + index);
while(index == bread.length) {
System.out.println("篮子里满了,开始等待!");
try {
this.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
bread[index] = b;
//System.out.println("生产了:" + bread[index]);
index++;
}
public synchronized Bread pop() {
System.out.println("消费前篮子里面包数为:" + index);
while(index == 0) {
System.out.println("篮子里为空,开始等待!");
try {
this.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
index--;
return bread[index];
}
}class Producer implements Runnable {
private Basket basket;
public Producer(Basket basket) {
this.basket = basket;
}
public void run() {
for(int i=0; i<10; i++) {
Bread bread = new Bread("第" + i + "个面包");
basket.push(bread);
System.out.println("生产了: " + bread);
try {
Thread.sleep(1);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}class Consumer implements Runnable {
private Basket basket;
public Consumer(Basket basket) {
this.basket = basket;
}
public void run() {
for(int i=0; i<10; i++) {
System.out.println("消费了:" + basket.pop());
try {
Thread.sleep(1);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}上面是楼主的程序,楼主开启了两个线程,就出现了死等待
解决办法:
第一种:把while循化,给我if判断。
第二种:把this.notify改为this.notifyAll()