我读的是一篇文章,实际上是关于双重检查锁定的,但是我为示例中出现的代码中的一个更基本的失败而感到惊讶。在那里声明,实例的初始化(即,在构造函数返回之前发生的实例变量的写入)可能在将实例的引用写入共享变量
之后 重新排序(实例中的静态字段)。以下示例)。
使用以下定义的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
没有第一个线程同步的情况下“修复”此代码(即,它将永远不会打印)?
调用foo = new Foo();
涉及到一些操作,除非您引入适当的同步措施以防止同步,否则这些操作可能会重新排序:
a = 0
)a = 1
)没有适当的同步,步骤3和步骤4可能会重新排序(请注意,步骤2必须在步骤4之前发生),尽管x86架构上的热点不太可能发生。
为防止这种情况,您有几种解决方案,例如:
a
决赛foo
(使用同步的init
AND getter)。无需深入了解JLS#17,您可以阅读有关类初始化(强调我的意思)的JLS#12.4.1:
初始化代码不受限制的事实允许html" target="_blank">构建示例,在 该 示例中
,在评估其初始化表达式之前,当类变量的值仍具有其初始默认值时,就可以观察到该变量的值 ,但实际上这种示例很少见。(
这些示例也可以用于实例变量初始化
。)Java编程语言的全部功能在这些初始化程序中可用。程序员必须格外小心。这种功能给代码生成器带来了额外的负担,但是由于Java编程语言是并发的,因此无论如何都会出现这种负担。
问题内容: 什么时候实例变量被初始化?是在构造函数块完成之后还是之前? 考虑以下示例: 家长建设者 子init() 父Init() 儿童构造者 属性1:100 属性2:null 什么时候在堆中分配属性1和2的内存? 好奇地知道为什么属性2为NULL? 有设计上的缺陷吗? 问题答案: 什么时候在堆中分配属性1和2的内存? 整个对象的内存是在调用构造函数之前在调用运算符时分配的。在中为单个实例分配了内
本文向大家介绍tensorflow 初始化未初始化的变量实例,包括了tensorflow 初始化未初始化的变量实例的使用技巧和注意事项,需要的朋友参考一下 今日在Stack Overflow上看到一个问如何只初始化未初始化的变量,有人提供了一个函数,特地粘贴过来共大家品鉴: 通过tf.global_variables()返回一个全局变量的列表global_vars, 然后以python列表解析式的
问题内容: 直观上似乎很清楚,在Java中,实例变量初始化器是按照它们在类声明中出现的顺序执行的。 在我正在使用的JDK中,似乎确实是这种情况。例如,以下内容: 打印(换句话说,y选择的默认值z)。 实际可以保证此顺序吗?我一直在浏览JLS,找不到任何明确的确认。 问题答案: 是的。 se7 JLS在12.5执行部分中介绍了实例变量的初始化顺序: … 4.执行此类的实例初始值设定项和实例变量初始值
问题内容: 在Java中,声明类级别的实例变量而不初始化它会消耗内存吗? 例如:如果不使用初始化内存,是否使用任何内存? 细节: 我有一个巨大的超类,许多不同的子类(不足以拥有自己的超类)扩展了。某些子类不会使用超类声明的每个原语。我可以简单地将这些原语保留为未初始化状态,而仅在必要的子类中对其进行初始化以节省内存吗? 问题答案: 类中定义的所有成员都具有默认值,即使您没有显式初始化它们也是如此,
我做了一些挖掘,似乎在任何地方都找不到简单的答案,也许我找错了地方。我只想按文件的修改时间排序,从最旧到最新。这可能吗?
问题内容: 我想要以下 在启动期间,主进程从文件加载一个大表并将其保存到共享变量中。该表有9列和1200万行,大小为432MB。 工作进程运行HTTP服务器,接受对大表的实时查询。 这是我的代码,显然没有实现我的目标。 我尝试将大表保存到MongoDB中,以便每个进程都可以轻松访问数据。但是表的大小是如此之大,以至于即使有索引,MongoDB仍需要约10秒才能完成我的查询。这太慢了,不能被我的实时