一、生产者和消费者问题
生产者消费者模式是一个十分经典的多线程协作的模式。
生产者和消费者问题包含了两类线程:一类是生产者线程用于生产数据,
一类是消费者数据用于消费数据。
//定义奶箱类
public class Box {
//定义成员变量牛奶
private int milk;
//定义成员变量表示奶箱的状态
private static boolean state = false;
//存储牛奶的操作
public synchronized void storeMilk(int milk) {
//如果有牛奶,等待消费
if (state) {
//这里注意要进行异常处理
try {
wait();
} catch (InterruptedException e) {
//打印异常信息到控制台
e.printStackTrace();
}
}
//如果没有牛奶就生产牛奶
this.milk = milk;
System.out.println("生产者将第" + this.milk + "瓶奶放入奶箱中");
//生产完毕,修改奶箱状态
state = true;
notify();
}
public synchronized void get() {
//如果没有牛奶,等待生产
if (!state) {
//异常处理
try{
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有,就获取牛奶
System.out.println("消费者拿到第" + this.milk + "瓶奶" );
//消费完毕之后修改奶箱状态
state = false;
notify();
}
}
public class Producer implements Runnable {
private Box b;
//构造方法,将奶箱对象作为参数
public Producer(Box b) {
this.b = b;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
//调用存储牛奶的方法
b.storeMilk(i);
}
}
}
public class Customer implements Runnable {
private Box b;
//构造方法,将奶箱对象作为参数
public Customer(Box b) {
this.b = b;
}
@Override
public void run() {
while(true) {
//调用获取牛奶的方法
b.get();
}
}
}
public static void main(String[] args) {
//创建奶箱对象
Box box = new Box();
//创建生产者和消费者对象,并将奶箱对象作为构造方法参数传入
Producer producer = new Producer(box);
Customer customer = new Customer(box);
//创建线程
Thread t1 = new Thread(producer, "生产者");
Thread t2 = new Thread(customer, "消费者");
//启动线程
t1.start();
t2.start();
}
运行结果如下:
生产者将第1瓶奶放入奶箱中
消费者拿到第1瓶奶
生产者将第2瓶奶放入奶箱中
消费者拿到第2瓶奶
生产者将第3瓶奶放入奶箱中
消费者拿到第3瓶奶
生产者将第4瓶奶放入奶箱中
消费者拿到第4瓶奶
生产者将第5瓶奶放入奶箱中
消费者拿到第5瓶奶
生产者将第6瓶奶放入奶箱中
消费者拿到第6瓶奶
生产者将第7瓶奶放入奶箱中
消费者拿到第7瓶奶
生产者将第8瓶奶放入奶箱中
消费者拿到第8瓶奶
生产者将第9瓶奶放入奶箱中
消费者拿到第9瓶奶
生产者将第10瓶奶放入奶箱中
消费者拿到第10瓶奶