生产者与消费者应用案例
多线程的开发中有一个经典的操作案例,就是生产者-消费者,生产者不断生产产品,消费者不断取走产品。
例如: 饭店里的有一个厨师和一个服务员,这个服务员必须等待厨师准备好膳食。当厨师准备好时,他会通知服务员,之后服务员上菜,然后返回继续等待。这是一个任务写作的示例,厨师代表生产者,而服务员代表消费者。
首先我们需要创建相应的类:
生产者类, 用于生产产品(我们这里的产品指的是Food,该类在下面展示)
假设我们生产的食物有两种”重庆小面”和”糖醋里脊”,
// 生产者类
class Producter implements Runnable {
private Food food;
public Producter(Food food) {
this.food = food;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if (i % 2 == 0) {
food.set("重庆小面", "就是好吃!!!");
} else {
// 是奇数的时候
food.set("糖醋里脊", "酸甜可口!");
}
}
}
}
消费者类,也就是消费食物
// 消费者类
class Customer implements Runnable {
private Food food;
public Customer(Food food) {
this.food = food;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
food.get();
}
}
}
消费和生产的对象, 食物类,这是我们的核心类, 同步代码在该类中体现.
注:在这里就用到了我在之前博客中提到的wait()方法和notify()方法,简单说明一下:
1. wait方法表示当前线程进入等待状态,会让出CPU并释放该监视器上的锁,但是要注意跟sleep方法的区别,sleep方法执行后是不会让出锁的,代码中执行了wait方法后会一直等待被“唤醒”, 也就是notify方法
2. notify方法, 用来唤醒已等待的方法,还有一个notifyAll方法,区别在于前者只唤醒其中一个,而后者则唤醒全部
// 消费的对象(数据), 食物类
class Food {
private String name;//菜名
private String efficacy;//功效
// true表示可以生产 false表示可以消费
private boolean flag = true;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEfficacy() {
return efficacy;
}
public void setEfficacy(String efficacy) {
this.efficacy = efficacy;
}
public Food(String name, String efficacy) {
super();
this.name = name;
this.efficacy = efficacy;
}
// 生产产品
public synchronized void set(String name, String efficacy) {
// System.out.println("重庆小面");
// 表示不能生产,但是可以消费,需要把时间让出啦
if (!flag) {
try {
// 等待跟休眠不同,sleep会进入等待但是不会让出锁
this.wait();// 表示当前线程进入等待状态,会让出CPU并释放该监视器上的锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.setName(name);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.setEfficacy(efficacy);
// 生产完成后
flag = false;
this.notify();// 唤醒该监视器上的其他线程(只是唤醒一个)
}
public synchronized void get() {
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(this.getName() + "->" + this.getEfficacy());
this.notify();
flag = true;
}
public Food() {
}
}
测试类
public class ThreadDemo4 {
public static void main(String[] args) {
Food food = new Food();
Producter p = new Producter(food);
Customer c = new Customer(food);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
代码执行结果:
以上纯属个人见解, 如有不足之处希望有高人指出, 定感激不尽, 如有喜欢交流学习经验请给我留言谢谢.
原创文章, 转载请注明出处