生产者消费者问题源程序

问题描述:

生产者消费者问题(Producer-consumer problem)是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。


要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。同样,也可以让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者。


如何模拟这个问题?

为了模拟这个问题,我们假设有一个篮子,这个篮子用于装刚刚生产出来的面包,这个篮子能够容纳的面包个数是固定的,所以,如果生产者(面包师傅)发现篮子已经满了,那么就返回厨房等待,当消费者拿掉了一个面包后,消费者会通知厨房的面包师傅,这个篮子已经不是满的了,可以再往里面加面包了。


同理,如果消费者发现篮子里没有面包了,那么他也只能在厅堂等着,当面包师傅往篮子里加了面包以后,面包师傅会通知那些在厅堂里等候拿面包的人,篮子里面已经有面包了。

Bread类用于模拟面包

public class Bread {
	int id;

	public Bread(int id) {
		this.id = id;
	}

	public String toString() {
		return "Bread: " + id;
	}
}

public class BreadBucket {
	int index = 0;
	Bread[] container;

	public BreadBucket(int size) {
		container = new Bread[size];
	}

	public synchronized void putBread(Bread bread) {
		while (index == container.length) {
			try {
				this.wait(); // The bucket is full, and the producer needs to wait
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		container[index] = bread;
		index++;
		System.out.println("+++++++New bread added: " + bread);
		System.out.println("+++++++Current # of bread in the bucket:" + index);
		this.notify(); // notify consumer, the bucket is not empty.

	}

	public synchronized void takeBread() {
		while (index == 0) {
			try {
				this.wait(); // The consumer needs to wait because the bucket is empty.
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		index--;
		Bread bread = container[index];
		System.out.println("-------Consumed bread: " + bread);
		System.out.println("-------Current # of bread in the bucket:" + index);
		this.notify(); // notify producer, the bucket is not full
	}
}

public class Consumer implements Runnable {

	BreadBucket container;

	public Consumer(BreadBucket container) {
		this.container = container;
	}

	@Override
	public void run() {
		while (true) {
			container.takeBread();
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class Producer implements Runnable {

	BreadBucket container;
	int id = 1;

	public Producer(BreadBucket container) {
		this.container = container;
	}

	@Override
	public void run() {
		while (true) {
			Bread bread = new Bread(id++);
			container.putBread(bread);

			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class Test {

	public static void main(String[] args) {

		BreadBucket container = new BreadBucket(10);
		Producer p = new Producer(container);
		Consumer c = new Consumer(container);

		new Thread(p).start();
		new Thread(c).start();
	}
}

转载请注明出处:blog.csdn.net/beiyetengqing。


你可能感兴趣的:(多线程,生产者消费者问题)