经典问题-生产者和消费者问题

来源:互联网 发布:李华清经济学考研知乎 编辑:程序博客网 时间:2024/05/22 07:48

生产者和消费者是一个多线程同步的经典案例,该问题描述了两个共享固定大小缓冲区的线程,即所谓的“生产者”和“消费者”,顾名思义,生产者指的就是生产一定的数据量到缓冲区,而消费者就是从缓冲区取走一定的数据。

生产者和消费者问题要解决一个死锁问题,就是当缓冲区已经满的时候,生产者占着它等待消费者来取走数据,而消费者则等着生产者让出缓冲区的权利好取走数据,于是就相互等待,从而造成死锁。

本程序只有一个生产者和一个消费者,使用wait和notify(nitify)方法来避免死锁问题,这里得提一下wait和notify(notifyAll)方法,线程中的wait、notify以及notifyAll方法:都是定义在Object类中的final方法,即所有的类都默认拥有这3个方法,但只用于synchronized关键字作用的范围内,并且是搭配着一起使用;wait方法是通知当前线程等待并释放对象锁;notify方法是通知等待此对象锁的一个线程重新获得线程锁;notifyAll是唤醒所有等待此对象锁的线程。

public class ProducerConsumer {public static void main(String[] args) {SyncStack myStack = new SyncStack(6);Producer producer = new Producer(myStack);Consumer consumer = new Consumer(myStack);Thread t1 = new Thread(producer);Thread t2 = new Thread(consumer);t1.start();t2.start();}}class Bread {private int id;Bread(int id) {this.id = id;}public int getId() {return id;}}class SyncStack {private int size;private int index = 0;private Bread[] myBread;SyncStack(int size) {this.size = size;myBread = new Bread[size];}public synchronized void put(Bread bread) {while (index == size) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}myBread[index] = bread;++index;System.out.println("Producer puts bread: " + bread.getId());this.notify();}public synchronized Bread remove() {while (index == 0) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}--index;System.out.println("Consumer removers bread: " + myBread[index].getId());this.notify();return myBread[index];}}class Producer extends Thread {private SyncStack myStack;Producer(SyncStack myStack) {this.myStack = myStack;}public void run() {for (int i = 1; i <= 20; ++i) {myStack.put(new Bread(i));try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class Consumer extends Thread {private SyncStack myStack;Consumer(SyncStack myStack) {this.myStack = myStack;}public void run() {for (int i = 1; i <= 20; ++i) {Bread bread = myStack.remove();try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}


0 0
原创粉丝点击