Java 生产者消费者实现
2017-08-07 本文已影响514人
被称为L的男人
《Java 编程思想》中,使用 厨师-服务员 来表示:生产者、消费者。
思路
chef 在 有 meal 的时候,会释放锁;在制作 meal 时,会获取 waitPerson 的锁,制作完 meal 后,唤醒所有的 waitPerson;
waitPerson 在 没有 meal 的时候,会释放锁;在消费 meal 后,会将 meal 置为 null,操作期间需要获得 chef 的锁。
实现
public class Restaurant {
Meal meal;
ExecutorService exec = Executors.newCachedThreadPool();
WaitPerson waitPerson = new WaitPerson(this);
Chef chef = new Chef(this);
public Restaurant() {
exec.execute(chef);
exec.execute(waitPerson);
}
public static void main(String[] args) {
new Restaurant();
}
}
public class Meal {
private final int orderNum;
public Meal(int orderNum) {
this.orderNum = orderNum;
}
@Override
public String toString() {
return "Meal " + orderNum;
}
}
public class Chef implements Runnable{
private int count = 0;
private Restaurant restaurant;
public Chef(Restaurant restaurant) {
this.restaurant = restaurant;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) { // shutdownNow 后,会退出循环
synchronized (this) {
// 如果有 meal,则释放锁,等待
while (restaurant.meal != null) {
wait();
}
}
if (++ count == 10) {
System.out.println("Out of 10");
restaurant.exec.shutdownNow();
}
synchronized (restaurant.waitPerson) {
restaurant.meal = new Meal(count);
restaurant.waitPerson.notifyAll();
}
TimeUnit.SECONDS.sleep(1);
}
} catch (Exception e) {
System.out.println("Chef interrupted");
}
}
}
public class WaitPerson implements Runnable{
private Restaurant restaurant;
public WaitPerson(Restaurant restaurant) {
this.restaurant = restaurant;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.meal == null) {
wait();
}
}
System.out.println("WaitPerson got " + restaurant.meal);
synchronized (restaurant.chef) {
restaurant.meal = null;
restaurant.chef.notifyAll();
}
}
} catch (Exception e) {
System.out.println("WaitPerson interrupted");
}
}
}