首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >易失式int多线程中的兴趣案例

易失式int多线程中的兴趣案例
EN

Stack Overflow用户
提问于 2016-04-16 11:20:05
回答 1查看 110关注 0票数 4

好的。我编写了代码,得到了意想不到的结果,我不知道如何解释这个结果。有人能帮我吗?

代码语言:javascript
复制
public class JMM {
static volatile Boolean ready = false;
static volatile int data = 0;

public static void main() {
    Log.d("JMM", "start");
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data = 1;
            ready = true;
        }
    }).start();

    for(int i = 0; i < 100; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (!ready)
                    Log.d("JMM", "second thread data " + data);
            }
        }).start();
    }
}
}

我在Nexus 5上执行了它(它有4个核心):

代码语言:javascript
复制
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MM.main();
}

结果:

D/JMM:第二个线程数据0 ..。 D/JMM:第二个线程数据0 D/JMM:第二个线程数据0 D/JMM:第二个线程数据0 D/JMM:第二个线程数据0 D/JMM:第二个线程数据0 D/JMM:第二个线程数据1 D/JMM:第二个线程数据1 D/JMM:第二个线程数据1 D/JMM:第二个线程数据0 D/JMM:第二个线程数据0 D/JMM:第二个线程数据1 D/JMM:第二个线程数据1 D/JMM:第二个线程数据1 D/JMM:第二个线程数据1

我想要什么?在默认情况下,该int是原子类型(但是我以前写过易失性的),它没有缓存它的值。但是我看到不同的线程在同一时刻从一个字段读取不同的值。谁能向我解释这件事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-17 05:03:35

考虑一下在这一行发生了什么:

代码语言:javascript
复制
Log.d("JMM", "second thread data " + data);
  1. 读取data
  2. 将其转换为字符串并与“第二个线程数据”连接。
  3. 将两个args传递给Log.d
  4. 它最终会打印出消息

在第一步之后会发生很多事情,很有可能一个线程将一个接一个地启动步骤1,但是在它之前开始步骤4。例如:

代码语言:javascript
复制
Thread 1               | Thread 2
-----------------------+-----------------------
1. read "data"         |
2. concat string:      |
  "...data 0"          |
     <<< third thread updates data = 1 >>>
                       | 1. read "data"
                       | 2. concat string:
                       |   "... data 1"
                       | 3. invoke Log.d(...)
                       | 4. print message
                       |   with "... data 1"
3. invoke Log.d(...)   | 
4. print message       |
  with "data 0"        |
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36663445

复制
相关文章

相似问题

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