传统的生产者消费者问题,防止虚假唤醒

传统的生产者消费者问题,防止虚假唤醒

注意点:wait需要被放进while代码块中,防止虚假唤醒

存在虚假唤醒代码:

package com.example.juc;

public class TestPc {
    public static void main(String[] args) {

        A a = new A();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.increase();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.decrease();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.increase();
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.decrease();
            }
        }, "D").start();
    }

}

class A {
    private int num;

    public synchronized void increase() {
        // 等待
        if (num != 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //
        System.out.println(Thread.currentThread().getName() + "-->" + ++num);
        notifyAll();
    }

    public synchronized void decrease() {
        // 等待
        if (num == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //
        System.out.println(Thread.currentThread().getName() + "-->" + --num);
        notifyAll();
    }
}

多运行几次可能会出现以下异常结果

A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
C-->1
A-->2
C-->3
A-->4
C-->5
A-->6
C-->7
A-->8
C-->9
A-->10
C-->11
A-->12
C-->13
D-->12
D-->11
D-->10
D-->9
D-->8
D-->7
D-->6
D-->5
D-->4
D-->3
B-->2
B-->1
B-->0
C-->1
B-->0
C-->1
B-->0
C-->1
B-->0

不存在虚假唤醒代码:将if 改为while即可

package com.example.juc;

public class TestPc {
    public static void main(String[] args) {

        A a = new A();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.increase();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.decrease();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.increase();
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                a.decrease();
            }
        }, "D").start();
    }

}

class A {
    private int num;

    public synchronized void increase() {
        // 等待
        while (num != 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //
        System.out.println(Thread.currentThread().getName() + "-->" + ++num);
        notifyAll();
    }

    public synchronized void decrease() {
        // 等待
        while (num == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //
        System.out.println(Thread.currentThread().getName() + "-->" + --num);
        notifyAll();
    }
}

A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
posted @ 2021-11-27 18:00  Oh,mydream!  阅读(28)  评论(0编辑  收藏  举报