设为首页 加入收藏

TOP

Java内存模型与指令重排(二)
2018-06-09 10:07:57 】 浏览:491
Tags:Java 内存 模型 指令
, 打印方法也简单提一下.


如下代码所示, 从红字注释的部分可以看出来, 


只有第一次进入循环之前, 检查了下stop的值, 不满足条件进入循环后, 


再也没有检查stop, 一直在做循环i++.


public void run() {
        int i = 0;
        while (!stop) {
            i++;
        }
        System.out.println("finish loop,i=" + i);
    }
 
 
  # {method} 'run' '()V' in 'VisibilityTest'
  ......
  0x02d486e9: jne    0x02d48715
  // 获取stop的值
  0x02d486eb: movzbl 0x64(%ebp),%ecx    ; implicit exception: dispatches to 0x02d48703
  0x02d486ef: test  %ecx,%ecx
  // 进入while之前, 若stop满足条件, 则跳转到0x02d48703, 不执行while循环
  0x02d486f1: jne    0x02d48703        ;*goto
                                        ; - VisibilityTest::run@12 (line 10)
  // 循环体内, i++
  0x02d486f3: inc    %edi              ; OopMap{ebp=Oop off=52}
                                        ;*goto
                                        ; - VisibilityTest::run@12 (line 10)
  0x02d486f4: test  %edi,0xe00000      ;*goto
                                        ; - VisibilityTest::run@12 (line 10)
        &

nbsp;                               ;  {poll}
  // jmp, 无条件跳转到0x02d486f3, 一直执行i++操作, 根本不检查stop的值
  // 导致死循环
  0x02d486fa: jmp    0x02d486f3
  0x02d486fc: mov    $0x0,%ebp
  0x02d48701: jmp    0x02d486eb
  // 跳出循环
  0x02d48703: mov    $0xffffff86,%ecx
  ......


解决方案也很简单, 只要给stop加上volatile关键字, 再次打印汇编代码, 发现他每次都会检查stop的值.


就不会出现无限循环了.


// 给stop加上volatile后
    public void run() {
        int i = 0;
        while (!stop) {
            i++;
        }
        System.out.println("finish loop,i=" + i);
    }


  # {method} 'run' '()V' in 'VisibilityTest'
  ......
  0x02b4895c: mov    0x4(%ebp),%ecx    ; implicit exception: dispatches to 0x02b4899d
  0x02b4895f: cmp    $0x5dd5238,%ecx    ;  {oop('VisibilityTest')}
  // 进入while判断
  0x02b48965: jne    0x02b4898d        ;*aload_0
                                        ; - VisibilityTest::run@2 (line 9)
  // 跳转到0x02b48977获取stop
  0x02b48967: jmp    0x02b48977
  0x02b48969: nopl  0x0(%eax)
    // 循环体内, i++
  0x02b48970: inc    %ebx              ; OopMap{ebp=Oop off=49}
                                &n
编程开发网

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java高并发之无锁与Atomic源码分析 下一篇Spring MVC接收数组类型参数

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }