一、概述
- 上一篇文章介绍到多个生产者和多个消费者时,会使生产者和消费者都处于wait等待状态,处于假死状态。
- 所以用notifyAll替换notify,唤醒所有处于等待中的线程。
二、代码
public class Thread12 {
private Integer index = 0;
private volatile boolean isProducer = false;
private Object LOCK = new Object();
public static void main(String[] args) throws Exception {
final Thread12 t12 = new Thread12();
// 生产者线程
new Thread(new Runnable() {
public void run() {
while (true) {
t12.producer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"P1").start();
new Thread(new Runnable() {
public void run() {
while (true) {
t12.producer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"P2").start();
// 消费者线程
new Thread(new Runnable() {
public void run() {
while (true) {
t12.comsumer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"C1").start();
new Thread(new Runnable() {
public void run() {
while (true) {
t12.comsumer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"C2").start();
}
public void producer() {
synchronized (LOCK) {
if(isProducer) {
// 已生产 -> 设置为wait -> 等待线程唤醒
System.out.println(Thread.currentThread().getName() + " producer: wait");
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
// 已被消费,再次生产 -> LOCK.notifyAll 唤醒所有线程
index++;
isProducer = true;
System.out.println(Thread.currentThread().getName() + " producer: " + index);
LOCK.notifyAll();
}
}
}
public void comsumer() {
synchronized (LOCK) {
if(isProducer) {
// 已生产 -> 消费 -> 唤醒所有线程
isProducer = false;
System.out.println(Thread.currentThread().getName() + " consumer: " + index);
LOCK.notifyAll();
} else {
// 已消费 -> 设置为wait -> 等待线程唤醒
System.out.println(Thread.currentThread().getName() + " comsumer: wait");
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}