欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程多生产多消费问题

程序员文章站 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();
    }
}