volatile
关于vilatile关键字,对比了《Java并发编程实战》和《深入理解Java虚拟机》,发现前者是忽悠,即使不是忽悠,也是不清不楚。后者才是真牛逼,还是国人写的,真是厉害啊。我的结论就是:1、共享可变的long、double变量如果没有锁保护,就要用vilatile,防止某些虚拟机应用了“非原子性协定”。其他所有地方,可以按建议使用vilatile,也可以不使用。2、所谓的vilati
关于volatile关键字,对比了《Java并发编程实战》和《深入理解Java虚拟机》,发现前者是忽悠,即使不是忽悠,也是不清不楚。后者才是真牛逼,还是国人写的,真是厉害啊。
我的结论就是:
1、共享可变的long、double变量如果没有锁保护,就要用volatile,防止某些虚拟机应用了“非原子性协定”。其他所有地方,可以按建议使用volatile,也可以不使用。
2、所谓的volatile“可见性”对于编程没有意义,虽然volatile变量在线程间同步快一些,但相应的减少了线程运算的性能。非volatile虽然同步慢一点,但是总会有的。
3、所谓的“禁止指令重排序优化”,仅对volatile变量生效,两个volatile变量,才会使执行时序遵守代码时序。要识别出哪些代码应该禁止优化,简直是一项比架构一个系统更加庞大的任务。所以直接java指定禁止重排序就好了,为了这点性能提高,不值。
喜闻乐见的如下代码:
private boolean goon = true;
// one thread
public void stop() {
goon = false;
}
// another thread
public void run() {
while (goon) {
dosomething();
}
}
不用volatile真的就不行了吗,会挂吗?显然不是的!
《深入理解Java虚拟机》和《Java并发编程实战》在这一点上面有矛盾,根据文章的逻辑性高低,我宁愿相信前者的理论。
《深入理解Java虚拟机》说,“禁止指令重排序优化”只能作用在volatile变量之间(参考12.3.3节,volatile特殊规则最后一段话),那么goon变量即使声明成volatile,也没有另一个volatile变量去和它配合适应这条规则啊,那这条规则在这里就没有用了。
根据这本书的说法推导,在这里把goon声明为volatile,作用就是可以省去缓存线程内存的步骤,类似于直接在主存上面进行变量读写。所以volatile变量的变化会更快的反映到其他线程内存,是快和慢的区别,不是有和无的区别。
《Java并发编程实战》却说,如果不用volatile修饰goon,那么在-server模式下,while (goon) {} 会被优化成 if (goon) while (true) {} 。但是我用实际代码验证了,并没有出现这种情况。
更多推荐
所有评论(0)