生产者 消费者 (wait notify)

来源:互联网 发布:游戏币充值软件 编辑:程序博客网 时间:2024/04/28 23:05

1、简介:

生产者-消费者(producer-consumer)问题是一个著名的线程同步问题。它描述的是:有一群生产者线程在生产产品,并将这些产品提供给消费者线程去消费。为使生产者与消费者之间能够并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者将它所生产的产品放入一个缓冲区中;消费者可以从一个缓冲区中取走产品产生消费。尽管所有的生产者线程和消费者线程都是以异步方式运行的,但他们之间必须保持同步,即不允许消费者到一个空缓冲区去消费,也不允许生产者向一个已经被占用的缓冲区投放产品。【转】

2、 wait()、notify(),notifyAll()的使用

obj.wait()方法将使本线程挂起,并释放obj对象的monitor。只有其他线程调用obj对象的notify()或notifyAll()时,才可以被唤醒。
obj.notifyAll()方法唤醒所有该obj对象相关的沉睡线程,然后被唤醒的众多线程开始竞争obj对象的monitor占有权,最终得到的那个线程会继续执行下去,但其他线程还将继续等待。
obj.notify()方法是随机唤醒一个沉睡线程。
wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,
如:
synchronized(x){
x.notify()
//或者wait()
}
以上内容说明了为什么调用wait(),notify(),notifyAll()的线程必须要拥有obj实例对象的monitor占有权。
wait(),notify(),notifyAll() 方法必须在synchronized 方法内调用

每个对象实例都有一个等待线程队列。这些线程都是等待对该对象的同步方法的调用许可。对一个线程来说,有两种方法可以进入这个等待线程队列。一个是当其他线程执行同步方法时,自身同时也要执行该同步方法;另一个是调用obj.wait()方法。
当同步方法执行完毕或者执行wait()时,其他某个线程将获得对象的访问权。当一个线程被放入等待队列时,必须要确保可以通过notify()的调用来解冻该线程,以使其能够继续执行下去。

3 例子:

public class Queue {List<String> list=new LinkedList<String>();public synchronized String getRequest(){if (list.size()==0) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return list.remove(0);}public synchronized void putRequest(String msg){list.add(msg);this.notifyAll();}}

生产者:
import java.util.Random;public class Producer extends Thread {private Queue queue;private String clientName;public Producer(Queue queue, String clientName) {super(clientName);this.queue = queue;this.clientName = clientName;}@Overridepublic void run() {// TODO Auto-generated method stubsuper.run();System.out.println("开始生产");for (int i = 0; i < 10; i++) {queue.putRequest(new Random().nextInt(1000)+" ");}System.out.println("生产结束");}}

消费者:
public class Consumer extends Thread {private boolean stop = false;private Queue queue;public Consumer(boolean stop, Queue queue) {super();this.stop = stop;this.queue = queue;}public void shutdown() {stop = true;this.interrupt();try {this.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void run() {// TODO Auto-generated method stubsuper.run();System.out.println("开始消费");while (!stop) {System.out.println("..");System.out.println("Consumer"+queue.getRequest());}System.out.println("[消费结束] shutdown.");}}

Mian:
public static void main(String[] args) {// TODO Auto-generated method stubQueue queue=new Queue();Consumer consumer=new Consumer(false, queue);consumer.start();for (int i = 0; i < 1; i++) {Producer rroducer=new Producer(queue, " >>"+i);rroducer.start();}}




参考:
http://blog.csdn.net/aming2006/article/details/4463979
http://hi.baidu.com/bayuehu1974/item/1c9a45ff92937755c9f337bd


原创粉丝点击