大佬教程收集整理的这篇文章主要介绍了是否可以对实例初始化进行重新排序并分配给共享变量?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
调用foo = new Foo();
涉及到一些操作,除非您引入适当的同步措施以防止同步,否则这些操作可能会重新排序:
a = 0
)a = 1
)没有适当的同步,步骤3和步骤4可能会重新排序(请注意,步骤2必须在步骤4之前发生),尽管x86架构上的热点不太可能发生。
为防止这种情况,您有几种解决方案,例如:
a
决赛foo
(使用同步的init
AND getter)。无需深入了解JLS#17,您可以阅读有关类初始化(强调我的意思)的JLS#12.4.1:
我读的是一篇文章,实际上是关于双重检查锁定的,但是我为示例中出现的代码中的一个更基本的失败而感到惊讶。在那里声明,实例的初始化(即,在构造函数返回之前发生的实例变量的写入)可能在将实例的引用写入共享变量
之后 重新排序(实例中的静态字段)。以下示例)。
使用以下定义的class
Foo
,在执行一个线程而执行Foo.initFoo();
另一个线程时System.out.println(Foo.foo.a);
,是否可以打印第二个线程0
(而不是1
抛出NullPointerException
),是否正确?
class Foo {
public int a = 1;
public static Foo foo;
public static void initFoo() {
foo = new Foo();
}
public static void thread1() {
initFoo(); // Executed on one thread.
}
public static void thread2() {
System.out.println(foo.a); // Executed on a different thread
}
}
从我对Java内存模型(以及其他语言的内存模型)的了解中,实际上这并不令我感到惊讶,但是直觉非常强烈地投票赞成这是不可能的(可能是因为涉及对象初始化并且对象初始化似乎如此)在Java中是神圣的)。
是否可以在0
没有第一个线程同步的情况下“修复”此代码(即,它将永远不会打印)?
以上是大佬教程为你收集整理的是否可以对实例初始化进行重新排序并分配给共享变量?全部内容,希望文章能够帮你解决是否可以对实例初始化进行重新排序并分配给共享变量?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。