需求:
在生产者/消费者模型中,生产者Producer负责生产数据,而消费者Consumer负责使用数据。多个生产者线程会在同一时间运行,生产数据,并放到内存中一个共享的区域。期间,多个消费者线程读取内存共享区,消费里面的数据。
要达到的效果就是,生产者Producer生产一件商品,消费者Consumer就消费一件。
分析:
在下面Java应用程序中,生产者线程向一个线程安全的堆栈缓冲区中写(PUSH)数据,消费者从该堆栈缓冲区中读(POP)数据,这样,这个程序中同时运行的两个线程共享同一个堆栈缓冲区资源。类Producer是生产者模型,其中的run方法中定义了生产者线程所做的操作,循环调用push()方法,不断将数据送入堆栈中,每次执行完push操作后,调用wait()方法,让线程停顿一会。类Consumer是消费者模型,循环调用pop方法,从PUPS中取出对应数据。
示意图:
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
//开辟四个线程。两个消费者消费、两个生产者生产
Thread t1 = new Thread(pro);
Thread t3 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
//一个共有的资源
class Resource
{
private String name;
private int count = 1;
private boolean flag = false; //标志位 当正在正在消费时为true,消费时为false
//生产
public synchronized void set(String name)
{
while(flag)
try{this.wait();}catch(Exception e){} //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。 是Object类的方法,相当于Thread.sleep(1000)的效果
this.name = name + "---" + count++;
System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
flag = true;
this.notifyAll();//唤醒其他所有的线程,就是让消费者着消费了。
}
//消费
public synchronized void out()
{
while(!flag)
try{wait();}catch(Exception e){}//在我消费的时候 你生产是停顿的
System.out.println(Thread.currentThread().getName() + "..消费者........." + this.name);
flag = false;
this.notifyAll();//唤醒生产者线程
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("+商品+");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
当然我们在这里没有添加结束线程的条件,加一个简单的计数器就可以搞定,这里只是为了说明问题而已。