锁定老帖子 主题:Effective Java的一小段代码
精华帖 (0) :: 良好帖 (1) :: 新手帖 (5) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-11-24
sswh 写道 nicklasy 写道 第二种可能,jvm会对
while(!stopRequested){ i++; }做优化,优化后程序执行流程变为 if(!stopRequested) { while(true){ i++; } },这种情况,backgroundThread线程永远不会结束。 看编译后的字节码,不会出现这种优化。 不知道是不是现在的编译器针对以前的编译器做了优化。 书上说,如果没有对stopRequested进行读写同步的话,编译器会将代码进行优化,如nicklasy所说的。 原文是这样的: 原文 写道 没有同步,虚拟机将这个代码: while(!done) i++; 转变成这样: if(!done) while(true) i++; 这是可以接受的。这种优化称作提升(hoisting),正是HopSpot Server VM的工作。 |
|
返回顶楼 | |
发表时间:2011-11-24
sswh 写道 nicklasy 写道 backgroundThread什么时候退出循环是不能确定的,有可能1秒后就退出了,也有可能永远不会退出。
但实际测试情况是stopRequested = true;这条语句后backgroundThread就退出了,重复测试N次都是这个结果,说明不是不确定的,而是确定的。 nicklasy 写道 第二种可能,jvm会对
while(!stopRequested){ i++; }做优化,优化后程序执行流程变为 if(!stopRequested) { while(true){ i++; } },这种情况,backgroundThread线程永远不会结束。 看编译后的字节码,不会出现这种优化。 ![]() 代码稍有改动。 这种优化是运行期优化,它有很多限制。它可能执行很长时间或者被调用很多次以后才会被优化,具体什么时候我也不清楚。可以参考一下这篇帖子。http://yueyemaitian.iteye.com/blog/1185297 |
|
返回顶楼 | |
发表时间:2011-11-24
Brera 写道 好像要java命令开启服务器端就是对的了
java -server 是不是这个,不记得了 这个是正解, 在windows上默认是以client的方式运行, 在linux上是server的方式 |
|
返回顶楼 | |
发表时间:2011-11-24
nicklasy 写道 sswh 写道 nicklasy 写道 backgroundThread什么时候退出循环是不能确定的,有可能1秒后就退出了,也有可能永远不会退出。
但实际测试情况是stopRequested = true;这条语句后backgroundThread就退出了,重复测试N次都是这个结果,说明不是不确定的,而是确定的。 nicklasy 写道 第二种可能,jvm会对
while(!stopRequested){ i++; }做优化,优化后程序执行流程变为 if(!stopRequested) { while(true){ i++; } },这种情况,backgroundThread线程永远不会结束。 看编译后的字节码,不会出现这种优化。 ![]() 代码稍有改动。 这种优化是运行期优化,它有很多限制。它可能执行很长时间或者被调用很多次以后才会被优化,具体什么时候我也不清楚。可以参考一下这篇帖子。http://yueyemaitian.iteye.com/blog/1185297 另外,我觉得这种优化是不会反映到.class文件中的。 |
|
返回顶楼 | |
发表时间:2011-11-24
nicklasy 写道 这种优化是运行期优化,它有很多限制。它可能执行很长时间或者被调用很多次以后才会被优化,具体什么时候我也不清楚。可以参考一下这篇帖子。http://yueyemaitian.iteye.com/blog/1185297
嗯,如果没有同步的话,在运行期做上面优化看上去也是合理的。 我再看一下资料。多谢! |
|
返回顶楼 | |
发表时间:2011-11-24
Cross_Lee 写道 书上说,如果没有对stopRequested进行读写同步的话,编译器会将代码进行优化,如nicklasy所说的。
原文是这样的: 原文 写道 没有同步,虚拟机将这个代码: while(!done) i++; 转变成这样: if(!done) while(true) i++; 这是可以接受的。这种优化称作提升(hoisting),正是HopSpot Server VM的工作。 收到,结合nicklasy的回复,原文的意思是JVM运行期的优化,不是编译期(或编译器)的优化。 |
|
返回顶楼 | |
发表时间:2011-11-24
boolean值为true,退出了啊。。。
|
|
返回顶楼 | |
发表时间:2011-11-24
new Thread().setDaemon(true)
|
|
返回顶楼 | |
发表时间:2011-11-24
去掉stopRequested = true; 这行就可以了,你前面的判断条件是!false,如果后面给true的话,判断条件就成了!true,那么肯定是结束了。
|
|
返回顶楼 | |
发表时间:2011-11-24
斐斐宝贝 写道 去掉stopRequested = true; 这行就可以了,你前面的判断条件是!false,如果后面给true的话,判断条件就成了!true,那么肯定是结束了。
不是这问题,这是同步的问题。代码没有对stopRequested 进行读写同步,按道理是那个循环不能读取到main线程里改过的boolean值,即应该一直循环下去。如果对stopRequested 进行读写锁的话,backgroundThread对stopRequested 是可见的,即循环会终止。 |
|
返回顶楼 | |