JUC:生产者消费者模式

文章目录

    • 虚假唤醒(spurious wakeup)
    • 生产者与消费者模板
    • 生产者与消费者模式:synchronized

虚假唤醒(spurious wakeup)

当需要条件判断使用wait()方法时,应该使用循环,而不是if,否则就可能会出现虚假唤醒(spurious wakeup)的情况

简单点理解,虚假唤醒就是除了理应被唤醒的线程之外,还另外唤醒了其它的线程,导致的数据的错误

虚假唤醒的原理:JUC:生产者消费者模式_第1张图片
例:

public class Test10 {
    public static void main(String[] args) {
        ProductAndCustomer productAndCustomer = new ProductAndCustomer();

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

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

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

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

class ProductAndCustomer{
    private int num;

    public synchronized void increment() throws InterruptedException {
        if(num != 0){
            wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+" num:"+num);
        notifyAll();

    }

    public synchronized void decrement() throws InterruptedException {
        if(num == 0){
            wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+" num:"+num);
        notifyAll();
    }
}

运行结果
JUC:生产者消费者模式_第2张图片

生产者与消费者模板

       1:等待条件
       2:业务逻辑
       3:唤醒其他线程

生产者与消费者模式:synchronized

将上面的代码改换成while即可

public class Test11 {
    public static void main(String[] args) {
    ProductAndCustomer11 productAndCustomer11 = new ProductAndCustomer11();

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

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

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

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

class ProductAndCustomer11{
    private int num;

    public synchronized void increment() throws InterruptedException {
        while (num != 0){
            wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+" num:"+num);
        notifyAll();

    }

    public synchronized void decrement() throws InterruptedException {
        while (num == 0){
            wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+" num:"+num);
        notifyAll();
    }
}

运行结果
JUC:生产者消费者模式_第3张图片

你可能感兴趣的:(JUC,java,多线程)