首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么“同步(新对象()){}”不是op?

为什么“同步(新对象()){}”不是op?
EN

Stack Overflow用户
提问于 2016-05-10 15:08:21
回答 2查看 3.6K关注 0票数 54

在以下代码中:

代码语言:javascript
复制
class A {
    private int number;

    public void a() {
        number = 5;
    }

    public void b() {
        while(number == 0) {
            // ...
        }
    }
}

如果调用方法b,然后启动一个触发方法a的新线程,则无法保证方法b永远不会看到number的更改,因此b可能永远不会终止。

当然,我们可以让number volatile来解决这个问题。然而,出于学术原因,让我们假设volatile不是一种选择:

JSR-133常见问题告诉我们:

退出同步块后,我们释放监视器,具有将缓存刷新到主内存的效果,因此由该线程编写的写入可以对其他线程可见。在进入同步块之前,我们获取监视器,的效果是使本地处理器缓存无效,以便从主内存中重新加载变量。

这听起来就像我只需要ab都能进入和退出任何synchronized-Block,不管他们使用什么监视器。更确切地说,听起来是这样的.

代码语言:javascript
复制
class A {
    private int number;

    public void a() {
        number = 5;
        synchronized(new Object()) {}
    }

    public void b() {
        while(number == 0) {
            // ...
            synchronized(new Object()) {}
        }
    }
}

...would消除了问题,并将保证b将看到对a的更改,从而也将最终终止。

然而,“常见问题”也明确指出:

另一个含义是,下面的模式--一些人用来强制设置记忆障碍的模式--不起作用: 同步(新对象()) {} 这实际上是一个无操作,您的编译器可以完全删除它,因为编译器知道在同一个监视器上不会有其他线程同步。您必须在一个线程看到另一个线程的结果之前设置一个发生关系。

这就让人困惑了。我认为同步语句会导致缓存刷新。主内存中的变化只能由同步在同一监视器上的线程看到,这肯定不能将缓存刷新到主存,特别是对于易失性线程,它基本上做的是我们甚至不需要监视器的事情,还是我弄错了?那么,为什么这是一个不操作,并没有导致b终止的保证?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-10 15:16:48

FAQ不是这件事的权威;JLS是的。节17.4.4指定在关系发生之前(17.4.5)与关系同步。有关的重点是:

  • 监视器m上的解锁操作同步-与m上的所有后续锁操作同步(其中“后继”根据同步顺序定义)。

由于这里的m是对new Object()的引用,而且它从未存储或发布到任何其他线程,所以我们可以确保在释放这个块中的锁之后,没有其他线程会获得对m的锁。此外,由于m是一个新的对象,所以我们可以肯定,在它上面没有任何先前解锁的操作。因此,我们可以确保没有任何操作与此操作正式同步。

从技术上讲,您甚至不需要进行完全的缓存刷新就可以达到JLS规范;这比JLS所要求的要多。一个典型的实现可以做到这一点,因为这是硬件允许您做的最简单的事情,但可以说,它正在“超越”。如果逃逸分析告诉优化编译器我们需要的更少,编译器可以执行得更少。在您的示例中,转义分析可以告诉编译器操作没有效果(由于上面的推理),并且可以完全优化。

票数 50
EN

Stack Overflow用户

发布于 2016-05-10 15:13:44

有些人使用下面的模式来强制设置记忆屏障,但这种模式不起作用:

它不一定是不操作,但规范允许它是不操作。当两个线程在同一个对象上同步时,规范只需要建立一个发生在两个线程之间的关系之前的同步,但是在对象的身份不重要的情况下,实现JVM实际上要容易一些。

我认为同步语句会导致缓存刷新。

Java语言规范中没有“缓存”。这个概念只存在于一些硬件平台和JVM实现的细节中。

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

https://stackoverflow.com/questions/37142411

复制
相关文章

相似问题

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