为了账号安全,请及时绑定邮箱和手机立即绑定

《Java并发编程实战》一段代码的疑惑

《Java并发编程实战》一段代码的疑惑

萧十郎 2019-02-19 04:09:20
《Java并发编程实战》3.1节的一段代码: public class NoVisibility { private static boolean ready; private static int number; private static class ReaderThread extends Thread { public void run() { while (!ready) Thread.yield(); System.out.println(number); } } public static void main(String[] args) { new ReaderThread().start(); number = 42; ready = true; } } 按照书中所讲,这段代码不一定输出42,有可能陷入死循环。原因是代码中没有足够的同步机制,无法保证主线程写入的ready他number对读线程是可见的。也有可能是0,原因是“重排序”,读线程看到了主线程写入的ready却没有看到number。但是经过多次测试,始终输出42,既没有输出0,也没有死循环。为了验证书中所说的主线程修改对读线程不可见,我改写了代码: public class NoVisibilityLoop { private static int number; private static class ReaderThread extends Thread { public void run() { while (true) { System.out.println(number); try { Thread.sleep(200); } catch (InterruptedException e) { } } } } public static void main(String[] args) throws InterruptedException { new ReaderThread().start(); Thread.sleep(1000); number = 42; } } 多次测试输出结果是:0000042424242这个结果说明了主线程写入的number对读线程是可见的。但是这本书的作者一堆大牛,不会搞错的。还请大家帮忙看看我的验证方法哪里出问题了,谢谢。运行环境:jdk 1.8.0_101,server模式。
查看完整描述

4 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

原文的意思是让你重复多次运行这段代码
大概运行几十次甚至上百次,可能出现一次死循环,而这个在实际开发中是不可取的

而这是代码设计缺陷的问题,所以建议不要这么编程,要保持主副线程的同步性不要用这样的写法,你继续往后看,这书既然这么说,可能会有别的解决方案来帮你理解他描述的原理

查看完整回答
反对 回复 2019-03-01
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

首先测试多次正确也不能保证完全就是正确的,其次这本书是jdk5和6了,jdk8估计做了些优化,

private static boolean ready;
private static int number;

private static class ReaderThread extends Thread {
    @Override
    public void run() {
        int i=0;
        while (!ready) {
            i++;
//                Thread.yield();
        }
        System.out.println(number);
    }
}

public static void main(String[] args) throws Exception {
    new ReaderThread().start();
    TimeUnit.MILLISECONDS .sleep(9);
    number = 42;
    ready = true;
}

把 thread.yield 换成 i++ 或者 sleep 与否 结果都有差别
这种执行顺序是指令重排决定的,不用volatile没法保证

查看完整回答
反对 回复 2019-03-01
?
POPMUISE

TA贡献1765条经验 获得超5个赞

应该是JDK版本差异造成的

查看完整回答
反对 回复 2019-03-01
  • 4 回答
  • 0 关注
  • 514 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信