多线程多生产多消费问题
程序员文章站
2022-05-02 17:33:16
...
生产者,消费者。
多生产者,多消费者的问题。
if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行!
notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
notifyAll解决了本方线程一定会唤醒对方线程的问题。
package demo.thread;
//烤鸭类
class RoastDuck {
private String name;
private int count = 0;
private boolean flag = false;
synchronized void set(String name) {
while (flag == true) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
count++;
System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name + count);
flag = true;
notifyAll();
}
/* 如果while改为if :
t0进来造鸭1,然后wait。
t1进来wait。
t2进来吃鸭1,吃完wait,并唤醒t0。
t2进来wait
t0醒来造鸭2,然后wait,并唤醒t1
t1直接造鸭3 !!! (烤鸭二还没吃呢)
如果notify改为notifyAll :
t0进来造鸭1,然后wait。
t1进来wait。
t2进来吃鸭1,吃完wait,并唤醒t0。
t2进来wait
t0醒来造鸭2,然后wait,并唤醒t1
t1直接wait (全wait了)
//毕向东JavaSE基础视频14 27-多线程(线程间通信-多生产者多消费者问题解决) 8min处
*/
synchronized void eat() {
while (flag == false) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "...消费者........" + this.name + count);
flag = false;
notifyAll();
}
}
//生产者
class Producer implements Runnable {
private RoastDuck r;
Producer(RoastDuck r) {
this.r = r;
}
public void run() {
while (true) {
r.set("烤鸭");
}
}
}
//消费者
class Consumer implements Runnable {
private RoastDuck r;
Consumer(RoastDuck r) {
this.r = r;
}
public void run() {
while (true) {
r.eat();
}
}
}
class RoastDuckTest {
public static void main(String[] args) {
RoastDuck r = new RoastDuck();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
t0.start();
t1.start();
t2.start();
t3.start();
}
}