黑马程序员-java多线程生产者消费者问题
/**
* 要求:生产一个产品,消费一个产品
*
* 为什么要定while判断标记
* 原因:让被唤醒的线程再一次判断标记。
*
* 为什么定义notifyAll
* 因为需要唤醒对方线程
* 因为只用notify,容易出现只唤醒本方线程,导致程序中的所有线程都等待。
*
*/
class Resource
{
private String name;
private int count=1;
private boolean flage=false;
//提供公共访问方法
//生产商品
public synchronized void set(String name) //用 synchronized锁定方法,保证一次只能生产一个商品,生产一个消费一个{
//if(flage)
while(flage) //使用while让被唤醒的线程再一次判断标记。
{
try {
this.wait(); //等待商品被消费
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name+"-----"+count++;
System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name);
flage=true;
this.notifyAll(); //唤醒所有等待的线程,不用notify()是防止所有的线程都处于等待状态
}
//消费商品
public synchronized void out(){
//if(!flage)
while(!flage)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"--消费者--"+this.name);
flage=false;
this.notifyAll();
}
}
//定义生产者类
class Producer implements Runnable
{
Resource r=new Resource();
public Producer(Resource r)
{
this.r=r;
}
int x=0;
public void run()
{
while(true)
{
if(x==0)
{
r.set("产品"); //给产品命名
}
else
r.set("canp");
x=(x+1)%2;
}
}
}
class Consumer implements Runnable
{
Resource r=new Resource();
Consumer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.out(); //消费产品
}
}
}
//主函数
public class ProductConsumerDemo {
public static void main(String[] args)
{
Resource r=new Resource();
//开启两个生产者线程、两个消费者线程
new Thread(new Producer(r)).start();new Thread(new Producer(r)).start();
new Thread(new Consumer(r)).start();
new Thread(new Consumer(r)).start();
}
}
//当有多个生产者和消费者的时候,可能出现生产的商品没有被消费,或者同一商品被消费两次
//必须使用while循环,notifyAll(),即唤醒本方又唤醒对方