2017-03-06 11 views
0

在练习中引用java书中的并发:为什么volatile读取总是无人参与?

同步的性能成本来自多个来源。 由同步和易失性提供的可视性保证可能需要使用称为内存屏障的特殊指令,可以使用高速缓存刷新或无效,刷新硬件写入缓冲区以及停止执行管线。内存屏障也可能具有间接的性能影响,因为它们禁止其他编译器优化;大多数操作不能用存储器 重新排序。在评估同步对性能的影响时,它对于区分竞争性和无竞争性的同步非常重要。同步机制针对 无竞争案例进行了优化(易失性总是无人参与),并且在此 写入时,对于大多数系统而言,“fast_path”无关的同步性能范围为20至250个时钟周期。

你能澄清一下吗? 如果我有大量线程读取易变变量会怎么样?

您能否提供争用定义?

是否有工具来测量争用?它是衡量哪些价值?

回答

3

您能澄清一下吗?

这是一个涉及很多话题的密集段落。您要求澄清哪些主题或主题?你的问题太广泛,不能令人满意地回答。抱歉。

现在,如果您的问题是特定于无约束同步,这意味着JVM中的线程不必阻止,获取畅通/通知,然后回到阻塞状态。

引擎盖下,JVM使用特定硬件内存屏障,以确保

  1. 一个volatile场总是读出和写入/从主内存中,而不是从CPU /内核缓存,并
  2. 你线程不会阻止/取消阻止来访问它。

没有争用。当你使用一个同步块OTH时,除了一个线程外,你的所有线程都处于阻塞状态,一个读取被同步块保护的数据。

我们称之为线程,即访问同步数据的线程,线程A

现在,这里是踢球,当线程A与数据做和存在的synchronized块,这将导致JVM来唤醒所有其他线程正在/在等待线程A退出同步块。

他们都醒了(这是昂贵的CPU /内存明智)。他们都试图争夺同步块。

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

但是只有一个人得到它并进入。所有其他人回去睡觉,种,在所谓的被阻止的状态。这也是昂贵的,资源明智的。

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

这就是让同步模块昂贵的原因。现在,需要注意的是:在JDK 1.4之前,它过去非常昂贵。那是17年前。 Java 1.4开始看到一些改进(2003年IIRC)。

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

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

如果我有大量的线程读取volatile变量会怎么样?

就正确性而言,这无关紧要。无论线程的数量如何,A volatile字段将始终显示一致的值。现在

,如果你有一个非常大的数量的线程,性能会因为上下文切换,内存利用率等(而不是和/或访问volatile领域的必然主要是因为受到影响。

能您提供的争定义?

请不要采取了错误的方式,但如果你问这个问题,我怕你不做好充分准备用书就像你正在阅读的一个。

您将需要更具体的介绍并发性和争用。

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

此致敬礼。

+0

好回答老兄。你谈论'synchronized'块,但是没有足够的锁定开销。这与阻止性讨论有关,但提及甚至保持并释放同步锁的性能影响是很好的。另外,当一个线程退出同步块时,只有一个线程被解锁,并非全部。 – Gray

+0

另外,“所有其他线程都变得疯狂(我能想到的最好的心理图像)来访问它”是错误的。当一个线程解锁该锁时,等待该锁的队列中的第一个线程(如果有的话)被给予该锁。所有的线程都不会唤醒并将其扑灭。 – Gray

相关问题