踩坑体会:程序计数器线程私有是有道理的

复习Java JUC的时候写一个消费者生产者模式,结果不对。生产者老是多生产。研究了原因之后发现我的代码是这样的:

synchronized (this){
                if(chickens.size()>=size){
                    System.out.println("鸡满~~~~~~~~~");
                    this.wait();
                }
                chickens.add(new Chicken());
                System.out.println("加了之后有"+chickens.size()+"只鸡");
                this.notifyAll();
}

就是说,每次鸡满,wait的时候这个线程的运行地点会停在this.wait()这一行,而不是我以为的像synchronized一样,“放锁”和“代码块结束”在同一时间发生。当它拿到锁之后会从这一行开始继续往下运行。这时候原子性已经得不到保证了。
这也让我对“程序计数器”这个东西为什么要线程私有有了进一步理解:当自己进入阻塞状态,把锁让出去的时候,这个线程起码得知道自己跑到哪一行了,当然需要一个线程配一个程序计数器。
把代码改成这样之后,就成了正确的生产者消费者模式的代码。

synchronized (this){
                if(chickens.size()>=size){
                    System.out.println("鸡满~~~~~~~~~");
                    this.wait();//往下走就没了!!!!!!
                }
                else{
                    chickens.add(new Chicken());
                    System.out.println("加了之后有"+chickens.size()+"只鸡");
                    this.notifyAll();
                }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值