生产者/消费者 - synchronized

时间:2022-05-14
本文章向大家介绍生产者/消费者 - synchronized,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

今天用synchronized实现了下生产者/消费者模式,遇到几个小问题,记录下。

public class SynchronizedDemo {

    //类似包子铺场景:包子最多提前做好50个,卖出去5个就再做;卖完了,买包子的就得等着
    //Synchronized版本

    private static int MAX = 50;
    private int number = 0;

    public void produce() throws InterruptedException {
        while (true) {
            synchronized (this) {
                if (number == MAX) {
                    //释放锁,出让cpu时间片,线程状态 - WAITING,等待唤醒
                    this.wait();
                    continue;
                }
                number++;
                System.out.println("+++++第 " + number + " 个包子被做出来了! - " + Thread.currentThread().getName());
                if (number > 20) {
                    //做出包子超过20个,买包子的赶紧买
                    this.notifyAll();
                }
            }
        }
    }

    public void consume() throws InterruptedException {
        while (true) {
            synchronized (this) {
                if (number == 0) {
                    //释放锁,出让cpu时间片,线程状态 - WAITING,等待唤醒
                    this.wait();
                    continue;
                }
                System.out.println("-----第 " + number + "个包子被买了! - " + Thread.currentThread().getName());
                number--;
                if (number < MAX - 5) {
                    //包子空缺超过5个,通知做包子的赶紧做
                    this.notifyAll();
                }
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
        //5个做包子的
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    synchronizedDemo.produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        //20个买包子的
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                try {
                    synchronizedDemo.consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

produce()和consume()方法中在调用 this.wait() 后,之前手快写了个return。。。

排查了半天,重走了下逻辑才发现。
排查过程中,理解了下 return 和不启用 notifyAll() 的线程统计。

1. return + 启用notifyAll()

此时对应线程就结束了,会看到有几个线程(4-5个)处于WAITING状态。

2. continue + 不启用 notifyAll()

所有线程最终都会进入WAITING状态。

原文地址:https://www.cnblogs.com/hello-yz/p/16269644.html