首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java内存模型与并发读取

Java内存模型与并发读取
EN

Stack Overflow用户
提问于 2017-07-18 19:07:23
回答 1查看 48关注 0票数 0
代码语言:javascript
复制
class C {
  Object o;
  public void set(Object o){
     if(this.o == null){ 
        this.o = o;
     }
  }
  public Object get(){
     return o;
  }
}

C c = new C();
代码语言:javascript
复制
C c = new C();  

Thread#1
Object o1 = c.get(); // 1
Object o2 = c.get(); // 2

Thread#2
c.set(new Object());

有可能是o2 == null && o1 != null吗?为什么?

为了明确我的意思,我编辑了:

如果我们有以下情况怎么办:

代码语言:javascript
复制
C c = new C(); // it is given at beginning 
1) Object o2 = c.o; // o2 is null. This operation was **reordered** before O `o1 = c.o. The JVM can do it because JMM allows do it. 
2) c.o = new Object()` //Thread #2 was executed 
3) O o1 = c.o // o1 is not null while o2 is.
EN

回答 1

Stack Overflow用户

发布于 2017-07-18 19:20:09

这是不可能的,尽管您有一个数据竞赛。

数据竞争是因为您在o周围的获取和设置是不同步的,这意味着不会发生--在与它们进行排序之前。可以通过让这两种方法都是synchronized,或者通过使o不稳定,或者通过其他一些方式来解决这个问题。

如果没有同步,JVM就可以重新排序其他线程看到的事件。从Thread1 1的角度来看,您有以下事件(为简化而内联的方法):

代码语言:javascript
复制
c.o = null; // initial value
o1 = c.o;
o2 = c.o;
c.o = new Object(); // from Thread2

对您来说幸运的是,有两个限制使此工作:

  1. c.c = null发生在所有其他操作之前(参见JLS 17.4.5)。
  2. 从给定线程的角度来看,在该线程上发生的操作总是按照它们在代码中出现的顺序进行(也是JLS 17.4.5)。所以对Thread1来说,o1 = c.o发生在o2 = c.o之前。(Thread2不必按顺序看那些读物.但它根本没有看到o1o2,所以没有问题。)

第一种情况意味着我们不能采取c.o = null操作,并在c.c = new Object()之后对其进行排序。第二个意味着,从thread 1的角度来看,您在文章底部提到的重新排序是不允许的(当然,Thread1是唯一能看到o1或o2的线程)。

结合这两个限制,我们可以看到,如果Thread1曾经看到c.o是非空的,那么它将永远不会看到它再次恢复为空。如果o1是非空的,那么o2也必须是。

请注意,这是非常变化无常的。例如,假设不只是设置c.o一次,而是Thread2设置了两次:

代码语言:javascript
复制
c.set("one");
c.set("two");

在这种情况下,可以看到o1是“2”,而o2是“1”。那是因为那里的行动是:

代码语言:javascript
复制
c.o = null; // initial value
o1 = c.o;
o2 = c.o;
c.c = "one"; // from Thread2
c.c = "two"; // from Thread2

JVM可以从Thread2重新排序项目,但是它认为合适,只要它们不出现在该c.c = null之前。特别是,这是有效的:

代码语言:javascript
复制
c.o = null; // initial value
c.c = "two"; // from Thread2
o1 = c.o;
c.c = "one"; // from Thread2
o2 = c.o;

通过将gets和sets同步到o,删除数据争用将修复这个问题。

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

https://stackoverflow.com/questions/45175163

复制
相关文章

相似问题

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