您的位置:首页 > 编程语言 > Java开发

Java多线程与并发(五)之生产者与消费者案例

2016-05-13 09:22 441 查看

生产者与消费者应用案例

多线程的开发中有一个经典的操作案例,就是生产者-消费者,生产者不断生产产品,消费者不断取走产品。

例如: 饭店里的有一个厨师和一个服务员,这个服务员必须等待厨师准备好膳食。当厨师准备好时,他会通知服务员,之后服务员上菜,然后返回继续等待。这是一个任务写作的示例,厨师代表生产者,而服务员代表消费者。

首先我们需要创建相应的类:

生产者类, 用于生产产品(我们这里的产品指的是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();
}

}


代码执行结果:



以上纯属个人见解, 如有不足之处希望有高人指出, 定感激不尽, 如有喜欢交流学习经验请给我留言谢谢.

原创文章, 转载请注明出处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 并发 多线程