复习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();
}
}