Java虚假唤醒(如何避免)

2022-02-22  本文已影响0人  你可以叫我老白

什么是假唤醒?

当一个条件满足时,很多线程都被唤醒了,但是只有其中部分是有用的唤醒,其它的唤醒都是无用功

1.比如说买货,如果商品本来没有货物,突然进了一件商品,这是所有的线程都被唤醒了,但是只能一个人买,所以其他人都是假唤醒,获取不到对象的锁

为什么 if会出现虚假唤醒

因为if只会执行一次,执行完会接着向下执行if()外边的

而while不会,直到条件满足才会向下执行while()外边的

避免虚假唤醒

/**

* 线程之间的通信问题:生产者和消费者的问题  等待唤醒 ,通知唤醒

* 线程交替执行 A B 操作同一个变量 num=0

*  A num+1

*  B num-1

*/

public class A {

    public static void main(String[] args) {

        Data data = new Data();

        new Thread(()->{

            for (int i = 0; i < 10; i++) {

                try {

                    data.increment();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        },"A").start();

        new Thread(()->{

            for (int i = 0; i < 10; i++) {

                try {

                    data.decrement();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        },"B").start();

        new Thread(()->{

            for (int i = 0; i < 10; i++) {

                try {

                    data.increment();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        },"C").start();

        new Thread(()->{

            for (int i = 0; i < 10; i++) {

                try {

                    data.decrement();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        },"D").start();

    }

}

//判断等待,业务,通知

class Data{// 数字 资源类

    private int number=0;

    //+1

    public synchronized  void increment() throws InterruptedException {

        while (number!=0){

          //等待

            this.wait();

        }

        number++;

        System.out.println(Thread.currentThread().getName()+"=>"+number);

        //通知其他线程 我+1完毕了

        this.notify();

    }

    //-1

    public synchronized  void decrement() throws InterruptedException {

        while (number==0){

            //等待

            this.wait();

        }

        number--;

        System.out.println(Thread.currentThread().getName()+"=>"+number);

        //通知其他线程  我-1完毕了

        this.notify();

    }

}

怎么产生虚假唤醒

把  while (product >=1) {}

换成  if (product >=1) {}

就会出现虚假唤醒

上一篇下一篇

猜你喜欢

热点阅读