为什么易失性读取始终是无竞争的?

时间:2017-03-06 13:12:26

标签: java concurrency locking volatile contention

在实践中引用书籍java并发:

  

同步的性能成本来自多个来源。   由synchronized和volatile提供的可见性保证可能   需要使用称为内存屏障的特殊指令   刷新或使缓存无效,刷新硬件写缓冲区和停止   执行管道。记忆障碍也可能具有间接性   性能后果因为它们会抑制其他编译器   优化;大多数操作都无法使用内存进行重新排序   障碍。在评估同步的性能影响时,它   区分竞争和非竞争是很重要的   同步。同步机制针对此进行了优化   无争用的情况( volatile始终是无竞争的),并且就此而言   写作,“fastͲpath”的性能成本是无条件的   对于大多数系统,同步范围为20到250个时钟周期。

你能更明确地澄清一下吗? 如果我有大量的线程读取易变量怎么办?

您能提供争用定义吗?

是否存在争用争用的工具?它的衡量标准是哪些?

1 个答案:

答案 0 :(得分:3)

  

你能更明确地澄清一下吗?

这是一个涉及很多主题的密集段落。您要求澄清哪些主题或主题?你的问题太宽泛,无法令人满意地回答。遗憾。

现在,如果您的问题特定于无竞争同步,则意味着JVM中的线程不必阻塞,取消阻止/通知,然后返回阻塞状态。

引擎盖下,JVM使用确保

的硬件特定内存屏障
  1. 始终从主内存读取和写入volatile字段,而不是从CPU /核心缓存中读取和写入
  2. 您的主题不会阻止/取消阻止访问它。
  3. 没有争论。当您使用同步块OTH时,所有线程都处于阻塞状态,除了一个,读取同步块保护的数据。

    让我们调用该线程,即访问同步数据的线程,线程A

    现在,这是踢球者,当线程A 完成数据并存在synchronized块时,这会导致JVM 唤醒所有其他线程等待线程A 退出同步块。

    他们都醒了(这是昂贵的CPU /内存)。他们都试图控制同步块。

    想象一下,一大群人试图通过一个小房间离开拥挤的房间。是的,这就是线程在尝试获取同步锁时的行为方式。

    但是只有一个人得到它并进入。所有其他人都回去睡觉,有点,在所谓的阻塞状态。资源方面,这也是昂贵的。

    因此,每当其中一个线程存在同步块时,所有其他线程都会疯狂(我能想到最好的心理图像)来访问它,一个获取它,所有其他线程都回到阻塞状态

    是什么让同步块变得昂贵。现在,这里有一个警告:它曾经是JDK 1.4之前非常昂贵的。那是17年前的事了。 Java 1.4开始看到一些改进(2003 IIRC)。

    然后,Java 1.5在2005年,12年前引入了更大的改进,这使得同步块更便宜。

    记住这些事情很重要。那里有很多过时的信息。

      

    如果我有大量线程读取易变量怎么办?

    在正确性方面,这并不重要。无论线程数如何,volatile字段始终显示一致的值。

    现在,如果您拥有非常多的线程,性能可能因上下文切换,内存利用率等而受到影响(并且不一定和/或主要是因为访问volatile字段。

      

    您能提供争用定义吗?

    请不要采取错误的方式,但如果你问这个问题,我担心你没有完全准备好使用像你正在阅读的那本书。

    您需要对并发性和争用性进行更基本的介绍。

    https://en.wikipedia.org/wiki/Resource_contention

    最好的问候。