当前位置:网站首页>JUC学习记录(2022.4.22)

JUC学习记录(2022.4.22)

2022-04-23 14:57:00 彬彬ice

1、虚假唤醒

多线程环境下,有多个线程执行了wait()方法,需要其他线程执行notify()或者notifyAll()方法去唤醒它们,假如多个线程都被唤醒了,但是只有其中一部分是有用的唤醒操作,其余的唤醒都是无用功;对于不应该被唤醒的线程而言,便是虚假唤醒。

package sync;
/** 当wait在if语句内时,因为进入前已经判断过条件,所以唤醒时(在哪睡,在哪醒)就不会再判断,继续执行下面语句,既发送虚假唤醒 */
class Calculator {
    
    private int num = 0;

    public synchronized void increment() throws InterruptedException {
    
        //if (num != 0) { //存在虚假唤醒
        // this.wait();
        //}
        while (num != 0) {
      //每次醒都重新判断,解决虚假唤醒
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName() + "+1,当前值:" + num);
        this.notifyAll();
    }

    public synchronized void decrement() throws InterruptedException {
    
        //if (num != 1) { //存在虚假唤醒
        // this.wait();
        //}
        while (num != 1) {
      //每次醒都重新判断,解决虚假唤醒
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName() + "-1,当前值:" + num);
        this.notifyAll();
    }

}

public class Compute {
    
    public static void main(String[] args) {
    
        Calculator calculator = new Calculator();
        new Thread(() -> {
    
            try {
    
                for (int i = 0; i < 10; i++) {
    
                    calculator.increment();
                }
            } catch (InterruptedException e) {
    
                e.printStackTrace();
            }
        }, "AA").start();
        new Thread(() -> {
    
            try {
    
                for (int i = 0; i < 10; i++) {
    
                    calculator.decrement();
                }
            } catch (InterruptedException e) {
    
                e.printStackTrace();
            }
        }, "BB").start();
        new Thread(() -> {
    
            try {
    
                for (int i = 0; i < 10; i++) {
    
                    calculator.increment();
                }
            } catch (InterruptedException e) {
    
                e.printStackTrace();
            }
        }, "CC").start();
        new Thread(() -> {
    
            try {
    
                for (int i = 0; i < 10; i++) {
    
                    calculator.decrement();
                }
            } catch (InterruptedException e) {
    
                e.printStackTrace();
            }
        }, "DD").start();
    }
}

版权声明
本文为[彬彬ice]所创,转载请带上原文链接,感谢
https://blog.csdn.net/xiaosong2001/article/details/124349053