您能否更清楚地说明这一点?
这是一个涉及很多主题的密集段落。您具体要求澄清哪个或哪些主题?你的问题太宽泛了,无法令人满意地回答。对不起。
现在,如果您的问题是特定于 uncontended 同步,这意味着 JVM 中的线程不必阻塞、解除阻塞/通知然后回到阻塞状态。
在底层,JVM 使用硬件特定的内存屏障来确保
-
volatile 字段始终从主内存读取和写入,而不是从 CPU/核心缓存读取和写入,并且
- 您的线程不会阻止/解除阻止来访问它。
没有争议。当您使用同步块 OTH 时,您的所有线程都处于阻塞状态,除了一个线程读取同步块保护的任何数据。
让我们调用那个线程,即访问同步数据的线程,线程 A。
现在,这是关键,当 线程 A 处理完数据并存在同步块时,这会导致 JVM 唤醒所有其他线程正在/正在等待 线程 A 退出同步块。
它们都被唤醒(这在 CPU/内存方面很昂贵)。他们都在争先恐后地试图获得同步块。
想象一下一大群人试图通过一个小房间离开拥挤的房间。是的,就像那样,这就是线程在尝试获取同步锁时的行为方式。
但只有一个人得到它并进入。所有其他人都回到睡眠状态,有点,在所谓的阻塞状态。这在资源方面也很昂贵。
因此,每当其中一个线程存在同步块时,所有其他线程都会发疯(我能想到的最佳心理形象)来访问它,一个得到它,然后所有其他线程都回到阻塞状态.
这就是使同步块变得昂贵的原因。现在,请注意:在 JDK 1.4 之前,它曾经非常昂贵。那是17年前的事了。 Java 1.4 开始出现一些改进(2003 IIRC)。
然后 Java 1.5 在 12 年前的 2005 年引入了更大的改进,这使得同步块的成本更低。
记住这些事情很重要。那里有很多过时的信息。
如果我有大量线程读取 volaile 变量怎么办?
就正确性而言,这并不重要。无论线程数如何,volatile 字段将始终显示一致的值。
现在,如果您有大量线程,性能可能会因为上下文切换、内存利用率等而受到影响(不一定和/或主要是因为访问 volatile 字段。
您能否提供争用定义?
请不要误会,但如果你问这个问题,恐怕你还没有完全准备好使用你正在阅读的书。
您将需要更基本的并发介绍,特别是争用。
https://en.wikipedia.org/wiki/Resource_contention
最好的问候。