首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么易失读总是无懈可击?

为什么易失读总是无懈可击?
EN

Stack Overflow用户
提问于 2017-03-06 13:12:25
回答 1查看 351关注 0票数 2

引用实践中的java并发书:

同步的性能代价来自于几个来源。同步和易失性提供的可见性保证可能需要使用称为内存屏障的特殊指令,这些指令可以清除或失效缓存、刷新硬件写缓冲区,以及延迟执行管道。内存障碍也可能有间接的性能后果,因为它们会抑制其他编译器的优化;大多数操作不能用内存屏障重新排序。在评估同步的性能影响时,区分竞争同步和非竞争同步非常重要。同步机制是针对非竞争情况优化的(易失性总是非竞争),在本文中,对于大多数系统来说,“快速Ͳ路径”非竞争同步的性能代价从20到250个时钟周期不等。

你能澄清清楚点吗?如果我有大量线程读取volaile变量怎么办?

您能提供争用定义吗?

有什么工具可以减少争论吗?在什么价值中,它是衡量标准?

EN

回答 1

Stack Overflow用户

发布于 2017-03-06 13:42:30

你能澄清清楚点吗?

这是一个密集的段落,涉及到许多主题。你具体要求澄清的是哪个或哪些主题?你的问题太宽泛了,不能令人满意地回答。抱歉的。

现在,如果您的问题是特定于非争用的同步,这意味着JVM中的线程不必阻塞、解除阻塞/通知,然后返回阻塞状态。

在幕后,JVM使用特定于硬件的内存屏障,以确保

  1. volatile字段总是从主内存中读取和写入,而不是从CPU/核心缓存中读取和写入,并且
  2. 您的线程不会阻止/取消阻塞来访问它。

没有争议。当使用同步块OTH时,所有线程都处于阻塞状态,只有一个线程处于阻塞状态,该线程正在读取由同步块保护的任何数据。

让我们将该线程称为访问同步数据的线程A。

现在,这里是一个kicker,当线程A与数据一起完成并存在同步块时,这将导致JVM唤醒正在/正在等待线程A退出同步块的所有其他线程。

它们都会醒来(这是昂贵的CPU/内存)。他们都竞相试图获得同步块。

想象一下,一大群人试图通过一个狭小的房间离开一个拥挤的房间。是的,就像那样,当线程试图获取同步锁时,这就是它们的工作方式。

但只有一个人得到并进入。所有其他人都会回到睡眠状态,某种程度上说,处于一种所谓的阻塞状态。就资源而言,这也是昂贵的。

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

这就是为什么同步块很昂贵的原因。现在,这里有一个警告:它曾经是非常昂贵的前JDK1.4。那是17年前的事了。Java1.4开始看到一些改进(2003年IIRC)。

随后,Java1.5在12年前的2005年引入了更大的改进,使得同步块更便宜。

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

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

就正确性而言,这并不重要。volatile字段将始终显示一致的值,而不管线程数如何。

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

您能提供争用定义吗?

请不要把它看错了,但是如果你在问这个问题,恐怕你还没有充分准备好使用像你正在读的那本书。

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

contention

诚挚的问候。

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

https://stackoverflow.com/questions/42626558

复制
相关文章

相似问题

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