参照马士兵老师的视频
但是在我按照他的方法实现的时候出现一个问题,就是还没生产出3号馒头就已经被吃掉了,后来仔细分析是因为打印生产和消费馒头的语句放的有问题,因为在run方法中,没有线程同步,所以虽然已经生产了一个,但是没打印出来就去消费了,然后打印消费的,再回来这个线程打印生产的,所以这样会产生问题。我的解决方法是把生产和消费的打印语句放在Basket的push和pop中,因为他们是线程同步的,生产或者消费的时候一定会打印出来再进行线程的切换...
package cn.lk.java.test;
class ManTou{
public int id;
public ManTou(int id) {
this.id = id;
}
public String toString() {
return "" + id;
}
}
class Basket {
int index = 0;
ManTou[] arry = new ManTou[6];
public synchronized void push(ManTou m) {
while(index == arry.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
arry[index] = m;
index ++;
System.out.println("======生产者生产了馒头" + m);
}
public synchronized ManTou pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index --;
ManTou m = arry[index];
System.out.println("消费者消费了馒头" + m);
return m;
}
}
class Producer implements Runnable{
Basket bb = null;
public Producer(Basket bb) {
this.bb = bb;
}
@Override
public void run() {
for(int i = 1; i <= 20; i++) {
ManTou m = new ManTou(i);
bb.push(m);
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }//生产出来一个就要让出线程给消费的线程去执行,出来的结果是生产一个消费一个
}
}
}
class Consumer implements Runnable{
Basket bb = null;
public Consumer(Basket bb) {
this.bb = bb;
}
@Override
public void run() {
for(int i = 1; i <= 20; i++) {
ManTou m = bb.pop();
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();//同上
// }
}
}
}
public class ProducerConsumer {
public static void main(String[] args) {
Basket bb = new Basket();
Producer chief1 = new Producer(bb);
Consumer customer1 = new Consumer(bb);
Thread t1 = new Thread(chief1);
Thread t2 = new Thread(customer1);
t1.start();
t2.start();
}
}
网友评论