使用场景请看上一篇博客Java基础之多线程-多生产多消费
话不多说,直接上代码:
顾客:
package cn.itcast.day07.demo02;
public class MultiConsumer implements Runnable {
private final Object LOCK;
public MultiConsumer(Object lock) {
this.LOCK = lock;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
synchronized (LOCK) {
while (MultiMain.products <= 0) { // 这里必须使用while,不能用if。
System.out.println(name + "因为没有包子,等待……");
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name + "吃掉了包子:" + MultiMain.products--);
LOCK.notifyAll(); // 通知对方两个厨子赶紧做,同时我的同伴顾客也会收到通知
} // sync
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
} // while
}
}
厨子:
package cn.itcast.day07.demo02;
public class MultiProducer implements Runnable {
private final Object LOCK;
public MultiProducer(Object lock) {
this.LOCK = lock;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
synchronized (LOCK) {
while (MultiMain.products >= 100) { // 这里必须使用while,不能用if。
System.out.println(name + "因为包子太多,等待……");
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name + "做出了包子:" + ++MultiMain.products);
LOCK.notifyAll(); // 通知对方两个顾客赶紧吃,同时我的同伴厨子也会收到通知
} // sync
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} // while
}
}
Main方法:
package cn.itcast.day07.demo02;
public class MultiMain {
public static int products = 50; // 初始50个包子
public static void main(String[] args) {
Object lock = new Object();
new Thread(new MultiConsumer(lock), "[顾客1]").start();
new Thread(new MultiConsumer(lock), "[顾客2]").start();
new Thread(new MultiProducer(lock), "[厨子A]").start();
new Thread(new MultiProducer(lock), "[厨子B]").start();
}
}
注:多生产多消费与单生产单消费的区别
区别在于在锁内判断包子数量的时候用的是if判断还是while判断:
单生产单消费二者都可以使用,但是建议使用if。
多生产多消费必须使用while,不可使用if。
if与while区别如下:
若使用if判断,在执行LOCK.wait()方法之后,若在重新获得锁之后,便接着向下执行,不会再重新走一遍if语句判断一下包子的数量,这在单生产单消费模式中并没有什么问题,因为只有一个顾客,没有别的人跟他抢包子;
但是在多生产多消费的模式下,如果包子还有一个,你不能保证在你没有吃的情况下另一位顾客也没有吃,所以在你获得锁之后要再次判断一下包子的数量,然而if并不支持这个操作,就要用到while了。
多生产多消费的模型如下: