- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
引自《Java 并发实践》一书:
The performance cost of synchronization comes from several sources. The visibility guarantees provided by synchronized and volatile may entail using special instructions called memory barriers that can flush or invalidate caches, flush hardware write buffers, and stall execution pipelines. Memory barriers may also have indirect performance consequences because they inhibit other compiler optimizations; most operations cannot be reordered with memory barriers. When assessing the performance impact of synchronization, it is important to distinguish between contended and uncontended synchronization. The synchronized mechanism is optimized for the uncontended case (volatile is always uncontended), and at this writing, the performance cost of a "fastͲpath" uncontended synchronization ranges from 20 to 250 clock cycles for most systems.
您能更清楚地说明这一点吗?如果我有大量读取 volaile 变量的线程怎么办?
你能提供竞争定义吗?
是否有衡量争用的工具?它以哪些值(value)观衡量?
最佳答案
Can you clarify this more clear?
这是一个涉及很多主题的密集段落。您具体要求澄清哪个或哪些主题?您的问题太宽泛,无法令人满意地回答。对不起。
现在,如果您的问题是特定于无竞争同步的,这意味着 JVM 中的线程不必阻塞、解除阻塞/通知然后返回到阻塞状态。
在底层,JVM 使用硬件特定的内存屏障来确保
volatile
字段总是从主内存中读取和写入,而不是从 CPU/核心缓存中读取和写入,并且 没有争执。当您使用同步块(synchronized block) OTH 时,您的所有线程都处于阻塞状态,除了一个线程,该线程读取同步块(synchronized block)保护的任何数据。
我们称该线程,即访问同步数据的线程,线程 A。
现在,更重要的是,当线程 A 处理完数据并存在同步块(synchronized block)时,这会导致 JVM 唤醒所有其他线程正在/正在等待线程 A 退出同步块(synchronized block)。
他们都醒了(这在 CPU/内存方面是昂贵的)。他们都争先恐后地试图控制同步块(synchronized block)。
想象一下,一大群人试图通过一个小房间离开拥挤的房间。是的,就像那样,这就是线程在尝试获取同步锁时的行为方式。
但只有一个人得到它并进入。所有其他人都回到 sleep 状态,某种程度上,处于所谓的阻塞状态。这在资源方面也是昂贵的。
因此,每当其中一个线程存在一个同步块(synchronized block)时,所有其他线程都会发疯(我能想到的最好的心理形象)来访问它,一个得到它,所有其他线程都回到阻塞状态.
这就是同步块(synchronized block)昂贵的原因。现在,这里有一个警告:在 JDK 1.4 之前它曾经非常昂贵。那是17年前。 Java 1.4 开始出现一些改进(2003 IIRC)。
然后 Java 1.5 在 12 年前的 2005 年引入了更大的改进,这使得同步块(synchronized block)的成本更低。
记住这些事情很重要。那里有很多过时的信息。
What if I have huge amount threads which read volaile variable ?
就正确性而言,这无关紧要。 volatile
字段将始终显示一致的值,无论线程数如何。
现在,如果您有大量线程,性能会因上下文切换、内存使用等而受到影响(不一定和/或主要是因为访问 volatile
字段。
Can you provide contention definition?
请不要误会,但如果你问这个问题,恐怕你还没有完全准备好使用你正在阅读的这本书。
您将需要更基本的并发介绍,尤其是争用。
https://en.wikipedia.org/wiki/Resource_contention
最好的问候。
关于java - 为什么volatile read总是无竞争?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42626558/
这将是一篇很长的文章,为了将其上下文化并提供尽可能多的信息,我必须仔细浏览各种链接和引号——这通常是我们进入 C/C++ 标准兔子洞的唯一方法。如果您对这篇文章有更好的引用或任何其他改进,请告诉我。但
我想知道 volatile 关键字与 register、const 和 static 结合的不同用途关键词。我不确定有什么影响,所以我认为: register volatile int T=10; 建
让我们考虑以下 Java 代码 int x = 0; int who = 1 Thread #1: (1) x++; (2) who = 2; Thread #2 while(who
有一个函数“remove_cv”(http://en.cppreference.com/w/cpp/types/remove_cv)可以删除常量和 volatile 。 我的问题是为什么可以从“con
我正在尝试在下面的“MpscQueue.h”中的嵌入式目标上实现多个生产者(通过中断)、单个消费者(通过应用程序线程)队列。 我想知道我是否可以安全地删除一些 volatile下面的用法(见内联问
我的问题适用于最初为 null 的字段,然后初始化为非 null 值,然后不再更改。 由于该字段需要尽快可供所有线程使用,因此我需要使用 volatile 。 但是,如果我想尽可能避免 volatil
我以前见过几次类似 fld = fld 的东西,但在所有这些情况下,可以消除虚拟写入并获得更好的性能。 public class Tst{ public volatile int fld =
看完this question和 this (尤其是第二个答案)我对 volatile 及其与内存屏障有关的语义感到非常困惑。 在上面的例子中,我们写入了一个 volatile 变量,这会导致一个 m
如下所示,该程序有一个共享 var flag,但不带 volatile : public class T { public static void main(String[] args) {
我明白声明 int *volatile ptr; 表示指针本身是volatile int a=10; int *volatile ptr=&a; 现在 ptr 和 a 都在更新。会不会导致访问ptr时
最近我需要比较两个 uint 数组(一个是 volatile 数组,另一个是非 volatile 数组),结果令人困惑,我一定是对 volatile 数组有一些误解。 我需要从输入设备读取一个数组并将
这两个 C 定义有什么区别? volatile uint32_t *ptr1 = (volatile uint32_t *)0x20040000; volatile uint32_t *ptr1 =
// structure is like this, but not exact formation. class queue { volatile List worksWaiting; }
考虑以下这段代码: struct S{ int i; S(int); S(const volatile S&); }; struct S_bad{ int i; }; vola
在 Windows x64 上,考虑到一些额外的见解,何时允许编译器将 ABI 标记为 volatile 的寄存器视为非 volatile 寄存器?我有一个反汇编函数,其中 r11 用于在函数调用后恢
我对下面的代码段有疑问。结果可能有 [0, 1, 0] 的结果(这是用 JCStress 执行的测试)。那么这怎么会发生呢?我认为应该在写入 Actor2 (guard2 = 1) 中的 guard2
好吧,假设我有一堆变量,其中一个声明为 volatile: int a; int b; int c; volatile int v; 如果一个线程写入所有四个变量(最后写入 v),而另一个线程读取所有
我试图理解为什么这个例子是一个正确同步的程序: a - volatile Thread1: x=a Thread2: a=5 因为存在冲突访问(存在对 a 的写入和读取),所以在每个顺序一致性执行中,
我正在编写一个需要同时支持 volatile 和非 volatile 实例的类( volatile 实例使用原子操作,非 volatile 实例使用常规操作),并且想知道我是否以正确的方式进行处理。到
我正在为 Cortex-M0 CPU 和 gcc 编写代码。我有以下结构: struct { volatile unsigned flag1: 1; unsigned flag2: 1
我是一名优秀的程序员,十分优秀!