首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实践中的JMM

实践中的JMM
EN

Stack Overflow用户
提问于 2016-08-26 23:33:14
回答 2查看 167关注 0票数 3

考虑以下用Java编写的多线程代码:

共享变量:

代码语言:javascript
复制
         boolean n; // non-volatile
volatile boolean v; //     volatile

线程1:

代码语言:javascript
复制
v = true;
System.out.println("n=" + n);

线程2:

代码语言:javascript
复制
n = true;
System.out.println("v=" + v);

假设最初是n = v = false

现在:

  • v=false 的输出是否意味着 n=true的输出?
  • 如果n是不稳定的,会发生什么变化?
  • 如果njava.util.List (因此n = true变成n.add("something")并将输出n=true转换为["something"]),会发生什么变化?
  • UPD3:,如果vAtomicBoolean,并且所有的读取和写入都是用compareAndSet语义执行的呢?

你能根据Java内存模型来说明你的立场吗?

UPD:请把System.out.println("n=" + n)当作对n的读物。v也是如此。

UPD2:,您能对第1和第4种情况提供一些分析,如JSR-133秒所示。8?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-27 00:43:05

实际上有三种代码可以执行的方法:

代码语言:javascript
复制
// Thread 1 runs first
T1: v = true;
T1: System.out.println("n=" + n);  // prints n=false

// Thread 2 runs second
T2: n = true;
T2: System.out.println("v=" + v);  // prints v=true
代码语言:javascript
复制
// They run in parallel, so assignments first, in any order
T1: v = true;
T2: n = true;

// Print statements second, in any order
T1: System.out.println("n=" + n);  // may print n=true or n=false (depends on CPU caching)
                                   // will print n=true if n is volatile
T2: System.out.println("v=" + v);  // prints v=true
代码语言:javascript
复制
// Thread 2 runs first
T2: n = true;
T2: System.out.println("v=" + v);  // prints v=false

// Thread 1 runs second
T1: v = true;
T1: System.out.println("n=" + n);  // may print n=true or n=false (depends on CPU caching)
                                   // will print n=true if n is volatile

v=false的输出是否意味着n=true的输出?

不是的。正如您在第三个场景中所看到的,n可以打印任意一个值。

如果n是不稳定的,会发生什么变化?

如注释所示,n将在场景2和3中打印true,而不是不确定的。

如果n是java.util.List (使n=true变为n.add(“某某物”),并将输出n=true转换为“某样东西”),那么会发生什么变化?

这假设在场景开始之前n已经是一个List,所以n的波动性并不重要。

n的打印是否会看到插入的值取决于列表的类型。如果不并发的列表,答案与问题1相同:它可能看到也可能看不到新的值。非并发列表的示例:

如果列表是并发的,它将看到新的值。同时列出的例子:

票数 0
EN

Stack Overflow用户

发布于 2016-08-27 00:01:57

这里有两个因素。

  • 您有一个volatile字段,但是
  • 您有一个对synchronizedSystem.out.println调用--这是读写屏障

在这两个线程中,您都在执行写入和读取操作。写障碍不能保证阅读障碍。

v=false的输出是否意味着n=true的输出?

如果你看到v=false,你可能会看到一个n=false,而visa反过来

如果n是不稳定的,会发生什么变化?

不太可能,您可能会看到行为的变化取决于您正在运行的体系结构,但是您仍然可以看到某些机器的不确定性行为。

如果n是java.util.List,会发生什么变化?

主要的变化是您正在替换一个写屏障,例如n = true使用一个读屏障n.method,这意味着您不再有一个写屏障(除了调用同步方法)

这样做意味着线程之间的一致性失败有更多的原因。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39175959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档