ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于生产者消费者的问题

2022-06-05 02:02:01  阅读:198  来源: 互联网

标签:count 消费者 生产者 关于 else notify wait


因为 https://blog.51cto.com/u_3631118/3119794 引发的问题

不去掉else

不去掉else影响的是生产者或者消费者的循环次数,如果二者循环次数不一致,就会导致循环慢的那个因为没有收到notify而处于wait状态,从而导致程序无法停止。

去掉else

如果去掉else,消费者每次都能notify生产者,即使生产者处在wait状态,消费者也能通知到,而上一种情况是有可能不会notify生产者,而生产者此时就在wait状态,也就到这了循环次数不一致的问题,如果消费者每次都能notify生产者,那么即使生产者处在wait状态,消费者也能通知到。这就是二者的不同之处:能够保证生产者处于wait状态,也能有消费者notify到。

以下为有问题的实验源代码,把消费者的else去掉就可以解决问题

package com.atguigu.sync;

/**
 * @author xiu
 * @create 2022-06-04 21:04
 */
public class ThreadDemo1 {
    public static void main(String[] args) {
        Share share = new Share();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
				    //生产者慢100毫秒,使问题暴露
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                share.add();
            }

        }, "add").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                share.decrease();
            }
        }, "decrease").start();
    }

}

class Share {
    int num = 0;
    int num2;
    int count = 0;

    //线程交替的三个步骤: 1.判断 2.干活 3.通知
//    判断和通知可以互换顺序,因为已经在锁里边,不会被抢走资源
//生产者方法
    public synchronized void add() {
        num2++;
        if (count == 2) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else
            count++;
        System.out.println("增加一个剩余" + count);
        notifyAll();
        System.out.println("生产者次数" + num2);
    }
//消费者方法
    public synchronized void decrease() {
        num++;
        if (count == 0) {
            try {
//                运行wait()之后会跳到方法结尾
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 带有else的情况
             *  去掉else其实就是改变notify的次数,如果notify的次数不够多,生产者总会因为生产满了而卡在wait,导致循环次数变少,而消费者的循环次数不会变少,
             * 就是说消费者循环停止之后生产者还没有结束循环,生产者还没有结束循环就会导致生产者生产满了之后达到wait状态,从而整个程序不能结束
             */

            /**
             * 不带else情况,就是所有情况下都会notify生产者,生产者即使因为生产满了,也会收到notify,此时消费者也会消耗掉,所以生产者不会wait,也就能和消费者配合,最后一起循环结束
             */
        } else {
            count--;
            System.out.println("消耗一个 剩余" + count);
            notifyAll();
            System.out.println("消费者次数" + num);
        }
    }
}

标签:count,消费者,生产者,关于,else,notify,wait
来源: https://www.cnblogs.com/xiuer211/p/16343218.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有