这是个线程同步的经典例子,源代码如下:
- <span style="font-size:16px;">package demo.thread;
- /**
- *经典生产者与消费者问题:生产者不断的往仓库中存放产品,消费者从仓库中消费产品。
- *其中生产者和消费者都可以有若干个。仓库容量有限,库满时不能存放,库空时不能取产品
- */
- public class ProducersAndConsumers {
- public static void main(String[] args) {
- Storage storage = new Storage();
- Thread consumer = new Thread(new Consumer(storage));
- consumer.setName("消费者");
- Thread producer = new Thread(new Producer(storage));
- producer.setName("生产者");
- consumer.start();
- producer.start();
- }
- }
- /**
- * 消费者
- */
- class Consumer implements Runnable {
- private Storage storage;
- public Consumer(Storage storage) {
- this.storage = storage;
- }
- @Override
- public void run() {
- storage.pop();
- }
- }
- /**
- * 生产者
- */
- class Producer implements Runnable {
- private Storage storage;
- public Producer(Storage storage) {
- this.storage = storage;
- }
- @Override
- public void run() {
- Product product = new Product("090505105", "电话");
- storage.push(product);
- }
- }
- /**
- * 产品类
- */
- class Product {
- private String id;// 产品id
- private String name;// 产品名称
- public Product(String id, String name) {
- this.id = id;
- this.name = name;
- }
- @Override
- public String toString() {
- return "(产品ID:" + id + " 产品名称:" + name + ")";
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- /**
- *仓库
- */
- class Storage {
- // 仓库容量为10
- private Product[] products = new Product[10];
- private int top = 0;
- // 生产者往仓库中放入产品
- public synchronized void push(Product product) {
- while (top == products.length) {
- try {
- wait();//仓库已满,等待
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- //把产品放入仓库
- products[top++] = product;
- System.out.println(Thread.currentThread().getName() + " 生产了产品"
- + product);
- notifyAll();//唤醒等待线程
- }
- // 消费者从仓库中取出产品
- public synchronized Product pop() {
- while (top == 0) {
- try {
- wait();//仓库空,等待
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- //从仓库中取产品
- --top;
- Product p = new Product(products[top].getId(), products[top].getName());
- products[top] = null;
- System.out.println(Thread.currentThread().getName() + " 消费了产品" + p);
- notifyAll();//唤醒等待线程
- return p;
- }
- }
- </span>
运行结果:
生产者 生产了产品(产品ID:090505105 产品名称:电话)
消费者 消费了产品(产品ID:090505105 产品名称:电话)