生产者与消费者的虚假唤醒问题

什么是虚假唤醒?

当一个条件满足时,唤醒了多个线程,其中部分线程不能被执行却执行了
比如操作一个变量:number初始是0,线程A对number进行+1,线程B对number进行-1,现在没有问题。但是,再有线程C对number进行+1和线程D对number进行-1时,就会出现不只是0和1的结果了。

明明加了锁,为什么还会产生负数情况?

是因为wait等待放在了if判断里面。
if判断只执行一次,然后就执行if()下边的了。而while会一直判断,直到满足条件才执行while()下边的代码

代码原因:

if (number != 0){
    this.wait();//等待
}

解决办法时把2个地方的if换成while就可以了。

while (number != 0){
    this.wait();//等待
}

下边是不会产生虚假唤醒的代码。(把while换成if就可以出现虚假唤醒)

/**
 * 虚假唤醒
 * 线程交替执行  操作同一个变量 num
 */
public class A {
    
    
    public static void main(String[] args) {
    
    
        Data data = new Data();

        new Thread(()->{
    
    
            for (int i = 0; i < 5; i++) {
    
    
                try {
    
    
                    data.increment();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        },"A").start();

        new Thread(()->{
    
    
            for (int i = 0; i < 5; i++) {
    
    
                try {
    
    
                    data.decrement();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        },"BB").start();

        new Thread(()->{
    
    
            for (int i = 0; i < 5; i++) {
    
    
                try {
    
    
                    data.increment();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        },"CCC").start();

        new Thread(()->{
    
    
            for (int i = 0; i < 5; i++) {
    
    
                try {
    
    
                    data.decrement();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        },"DDDD").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.notifyAll();
    }

    //执行 -1
    public synchronized void decrement() throws InterruptedException {
    
    
        while (number==0){
    
    
            this.wait();//等待
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"->"+number);
        //通知其他线程,-1完毕
        this.notifyAll();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42524288/article/details/106001951