Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 施工人员是否应设置门店屏障?_Java_C++_Java Memory Model_Memory Model - Fatal编程技术网

Java 施工人员是否应设置门店屏障?

Java 施工人员是否应设置门店屏障?,java,c++,java-memory-model,memory-model,Java,C++,Java Memory Model,Memory Model,你是否应该在施工人员中设置门店屏障 这里有一个例子。最初假设global\u f=f=r=0。 一个线程A创建一个对象,分配给一个字段,然后分配给一个全局变量: class Foo { int x; void Foo(int x) { this.x = x; } } f = new Foo(42); global_f = f; 另一个线程B从全局变量获取引用,然后读取字段 r = global_f.x; 假设执行时线程B从线程B读取对象引用,那么它

你是否应该在施工人员中设置门店屏障

这里有一个例子。最初假设
global\u f=f=r=0
。 一个线程A创建一个对象,分配给一个字段,然后分配给一个全局变量:

class Foo {
    int x;
    void Foo(int x) {
         this.x = x;
    }
}

f = new Foo(42);
global_f = f;
另一个线程B从全局变量获取引用,然后读取字段

r = global_f.x;
假设执行时线程B从线程B读取对象引用,那么它可以从
X
读入
r
?是否总是42岁

我对C++和java的行为感兴趣。据我对内存模型的理解,
r
不能保证为42


为了确保对象的字段被正确初始化,我们通常可以在构造函数的末尾设置存储屏障。这似乎在C++和java中都有缺陷。至少对于Java来说,最终字段的一切都很好,不是吗?这在实践中并不重要,因为至少在x86和AMD64上,存储屏障是NOP。但是,在ARM或POWER等其他体系结构上并非如此。

在Java中,除非将
x
字段声明为
final
,否则不能保证
r
将是
42


为了确保对象的字段被正确初始化,我们通常可以在构造函数的末尾设置存储屏障。这似乎在C++和java中都有缺陷。 这是一个评论,不是一个问题。然而,相反的观点是,在所有构造函数的末尾放置一个隐式屏障会在各种情况下导致不必要的性能损失;e、 g

  • 对于单线程代码
  • 对于未发布
    f
    的多线程代码
  • 对于多线程代码,通过同步方法保护对
    x
    的访问

和C++的内存模型是简单性和性能考虑之间的折衷。如果你过分追求简单(即设计出所谓的陷阱),多线程代码将不会给你人们想要/需要的加速。

C++only:内存障碍不会(不应该)自动添加,这是程序员的问题。下面的指导原则适用:“仅为您使用的内容付费规则”和多线程对于编译器的静态分析来说太复杂(编译器单独查看每个编译单元)。您需要缩小询问语言的范围。java和C++有不同的内存模型和语言语义。首先,类是C++中的值而不是引用。另一个是Java的
volatile
与C++有很大的不同,我不明白为什么要在这里单独列出构造函数。这种情况与设置
x
的任何其他方法调用没有区别。