1.Restaurant
package Produce;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;class Meal {
private final int orderNum;
public Meal(int orderNum) {
this.orderNum = orderNum;
}@Override
public String toString() {
return "Meal " + orderNum;
}
}class WaitPerson implements Runnable {
private Restaurant restaurant;public WaitPerson(Restaurant r) {
restaurant = r;
}@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.meal == null)
wait(); // 等待chef生产meal
}
System.out.println("Waitperson got " + restaurant.meal);
synchronized (restaurant.chef) {
restaurant.meal = null;
restaurant.chef.notifyAll();// 通知chef继续生产
}
}
} catch (InterruptedException e) {
System.out.println("WaitPerson interrupted");
}
}
}class Chef implements Runnable {
private Restaurant restaurant;
private int count = 0;public Chef(Restaurant r) {
restaurant = r;
}@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.meal != null)
wait();// 等待meal被拿走
}
if (++count == 10) {
System.out.println("Out of food,closing");
restaurant.exec.shutdownNow();//向每个线程发送Interrupt
return;//如果没有直接return 将多执行了下面的 Order up ,所以一般情况下都要直接return
}System.out.println("Order up! ");
synchronized (restaurant.waitPerson) {
// 对notifyAll()的调用必须先获得waitPerson的锁
restaurant.meal = new Meal(count);
restaurant.waitPerson.notifyAll();
}
TimeUnit.MILLISECONDS.sleep(500);//休眠一下是为了给shutdownNow留出时间
}
} catch (InterruptedException e) {
System.out.println("Chef interrupted");
}
}
}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();
}
}
2.使用java.util.concurrent.locks.Condition进行同步操作
Lock和Condition对象只有在更加困难的多线程问题中才是必需的。
package Produce;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class Car {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean waxOn = false;public void waxed() {
lock.lock();
try {
waxOn = true;// Ready to buff
condition.signalAll();
} finally {
lock.unlock();
}
}public void buffed() {
lock.lock();
try {
waxOn = false;// Ready for another coat of wax
condition.signalAll();
} finally {
lock.unlock();
}
}public void waitForWaxing() throws InterruptedException {
lock.lock();
try {
while (waxOn == false)
condition.await();
} finally {
lock.unlock();
}
}public void waitForBuffing() throws InterruptedException {
lock.lock();
try {
while (waxOn == true)
condition.await();
} finally {
lock.unlock();
}
}
}class WaxOn implements Runnable {
private Car car;public WaxOn(Car c) {
car = c;
}@Override
public void run() {
try {
while (!Thread.interrupted())
// while (true) //与使用这行效果一样
{
System.out.println("Wax On!");
TimeUnit.MILLISECONDS.sleep(200);
car.waxed();
car.waitForBuffing();
}
} catch (InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax On task");
}
}class WaxOff implements Runnable {
private Car car;public WaxOff(Car c) {
car = c;
}@Override
public void run() {
try {
while (!Thread.interrupted())
// while (true){
car.waitForWaxing();
System.out.println("Wax Off!");
TimeUnit.MILLISECONDS.sleep(200);
car.buffed();
}
} catch (InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax Off task");
}
}public class WaxOMatic2 {
public static void main(String[] args) throws InterruptedException {
Car car = new Car();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new WaxOff(car));
exec.execute(new WaxOn(car));
TimeUnit.SECONDS.sleep(5);
exec.shutdownNow();
}
}
java多线程之生存者与消费者(Java编程思想)