java - JMM 和发生之前

标签 java

我有一个关于 JMM 的问题。我知道什么是“之前发生”,但我不明白一件事。有一段代码:

private static int x = 0;
private static volatile boolean flag = false;

public static void main(String[] args) throws InterruptedException {

    new Thread(() -> {
        x = 10;
        while (!flag) ;
        System.out.println(x);
    }).start();

    x = 5;
    flag = true;
}

“X”中必须包含什么值,是否有规则来确定它? 也许在这种情况下,线程是否有某种顺序将某些值放入 X 中?

最佳答案

我们首先通过注释掉 x=10 来稍微简化一下程序。

private static int x = 0;
private static volatile boolean flag = false;

public static void main(String[] args) throws InterruptedException {

    new Thread(() -> {
        //x = 10;
        while (!flag) ;
        System.out.println(x);
    }).start();

    x = 5;
    flag = true;
}

在此示例中,将打印 5。为什么?

x=5
|
[program order rule]
|
flag=true
|
[volatile variable rule]
|
tmp1=flag
|
[program order rule]
| 
tmp2=x

因为发生在规则之前也是可传递的,所以 x=5 和 tmp2=x 之间存在发生在关系之前。

如果 x=10 未注释,则 10 和 5 是允许的结果。

关于java - JMM 和发生之前,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38546897/

相关文章:

java - Spring 3 中 BigDecimal 的格式化

java - Spring MVC 和 Liferay - 资源映射问题

java - Joda-Time 是否有一个名为 isToday 的方法

java - 如何改变 JTextArea 中只有一个字符串的大小?

java - Hibernate 缓存和 JdbcTemplate

Java/Selenium WebDriver : Focus Don't skip to Else If block when the warning message matches on webpage

java - android使用wowza发布视频的RTMP客户端

java - Netbeans 7.2.1 mac javadoc 未找到 Java Me

java - Grails 2.4.2 域不会保存超过 8 个字段

java - 如何将 RecyclerView 中显示的数据与 Firebase 中的文档关联