论坛首页 Java企业应用论坛

Effective Java的一小段代码

浏览 16800 次
精华帖 (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的工作。
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2011-11-24  
Brera 写道
好像要java命令开启服务器端就是对的了
java -server 是不是这个,不记得了


这个是正解, 在windows上默认是以client的方式运行, 在linux上是server的方式
0 请登录后投票
   发表时间: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文件中的。
0 请登录后投票
   发表时间:2011-11-24  
nicklasy 写道
这种优化是运行期优化,它有很多限制。它可能执行很长时间或者被调用很多次以后才会被优化,具体什么时候我也不清楚。可以参考一下这篇帖子。http://yueyemaitian.iteye.com/blog/1185297


嗯,如果没有同步的话,在运行期做上面优化看上去也是合理的。
我再看一下资料。多谢!
0 请登录后投票
   发表时间:2011-11-24  
Cross_Lee 写道
书上说,如果没有对stopRequested进行读写同步的话,编译器会将代码进行优化,如nicklasy所说的。

原文是这样的:

原文 写道

没有同步,虚拟机将这个代码:
while(!done)
  i++;

转变成这样:
if(!done)
  while(true)
    i++;

这是可以接受的。这种优化称作提升(hoisting),正是HopSpot Server VM的工作


收到,结合nicklasy的回复,原文的意思是JVM运行期的优化,不是编译期(或编译器)的优化。
0 请登录后投票
   发表时间:2011-11-24  
boolean值为true,退出了啊。。。
0 请登录后投票
   发表时间:2011-11-24  
new Thread().setDaemon(true)
0 请登录后投票
   发表时间:2011-11-24  
去掉stopRequested = true;  这行就可以了,你前面的判断条件是!false,如果后面给true的话,判断条件就成了!true,那么肯定是结束了。
0 请登录后投票
   发表时间:2011-11-24  
斐斐宝贝 写道
去掉stopRequested = true;  这行就可以了,你前面的判断条件是!false,如果后面给true的话,判断条件就成了!true,那么肯定是结束了。


不是这问题,这是同步的问题。代码没有对stopRequested 进行读写同步,按道理是那个循环不能读取到main线程里改过的boolean值,即应该一直循环下去。如果对stopRequested 进行读写锁的话,backgroundThread对stopRequested 是可见的,即循环会终止。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics