实质:
该案例模式是一个十分经典的多线程协作模式,所谓生产者消费者问题,实际上主要包含了两类线程:
- 生产者线程(生产数据)
- 消费者线程(消费数据)
通过共享数据区域间接将两者联系起来,生产者将生产的数据直接放在共享数据区域,消费者从共享数据区域中获取数据,彼此之间并不关心对方的行为。
分析:
- 奶箱类(Box):定义一个成员变量(表示第x瓶奶),提供set()(存储牛奶)和get()(获取牛奶)的方法。
- 生产者类(Producer):实现Runnable接口,重写run()方法,在方法中调用存储牛奶的操作。
- 消费者类(Customer):实现Runnable接口,重写run()方法,在方法中调用获取牛奶的操作。
- 测试类(BoxDemo):创建奶箱对象(共享数据区域)、创建生产者对象和消费者,把奶箱对象作为构造方法参数传递、创建两个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递、启动线程。
奶箱类(Box)package Thread; public class Box { private int milk; private boolean state = false; public synchronized void put(int milk) { // 如果有牛奶,等待 if (state) { try { wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } this.milk = milk; System.out.println("送奶工的第" + this.milk + "瓶奶。"); state = true; notifyAll(); } public synchronized void get() { // 如果没有牛奶 if (!state) { try { wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } System.out.println("消费者的第" + this.milk + "瓶奶。"); state = false; notifyAll(); } }
生产者类(Producer)
package Thread; public class Producer implements Runnable{ private Box b; public Producer(Box b){ this.b = b; } @Override public void run() { for (int i = 0;i<5;i++){ b.put(i); } } }
消费者类(Customer)
public class Customer implements Runnable { private Box b; public Customer(Box b) { this.b = b; } @Override public void run() { while (true) { b.get(); } } }
测试类(BoxDemo)
package Thread;
public class BoxDemo {
public static void main(String[] args) {
Box b = new Box();
Producer p = new Producer(b);
Customer c = new Customer(b);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
运行结果: