我真的很新的Java和我读了synchronized是Java“非常昂贵”。所有我想知道的是什么,是昂贵的,它是如何昂贵?

感谢。

有帮助吗?

解决方案

也许这不是那么糟糕,因为你认为

它曾经是可怕的(这可能是为什么你看,这是“非常昂贵”)。这些记因可能需要很长的时间来消亡

  

如何昂贵是同步?

     

由于涉及高速缓存刷新和无效的规则,在Java语言中的同步块通常比通过许多平台提供的关键部分的设施,其通常用原子实现的“测试和设置位”机器指令更昂贵。即使当一个程序只包含在单个处理器上运行的单个线程,同步方法调用仍比非同步的方法调用慢。如果同步实际上需要争用锁,性能损失是显着更大的,因为会有需要几个线程切换和系统调用。

     

幸运的是,在JVM中连续改进都提高了整体的Java程序的性能和与每个释放减少同步的相对成本,和未来的改进预期。此外,同步的性能代价往往是夸大了。一个众所周知的源已列举了一个同步的方法调用是比非同步方法调用慢高达50倍。虽然这种说法可能是正确的,它也是非常容易引起误解,并导致很多开发商为了避免在需要的情况下甚至同步。

话虽如此 - 并发编程仍然可能会很慢,但没有这么多的是纯Java的错了。有细和粗锁之间的权衡。太粗显然是不好的,但它可能是太细太,因为锁具有非零成本。

要考虑竞争下的特定资源是很重要的。机械硬盘是一个例子,其中多个线程可导致更糟性能。

其他提示

有昂贵的,因为如果使用的是线程,多个线程都需要经过同步的代码段,其中只有一个可在一个时间被执行。

它像一个瓶颈。

当你使用一个单独的线程它甚至昂贵的,因为它有,如果他被允许运行反正检查。

如果您减少使用同步段的线程将不会有停下来看看他们是否能运行(当然,他们没有共享数据)

的同步工作原理可被发现高水平概述

http://img20.imageshack.us/img20/2066/monitor28synchronizatioc.png

<子>一个Java式显示器

这是不是特定于Java。同步可以在任何多线程环境中,如果没有做正确被认为是“昂贵”。无论是特别坏的在Java中,我不知道。

它可以防止线程如果它们使用相同的资源同时运行。但是,因为它们的的使用相同的资源,有没有更好的选择(它必须做)。

问题是,人们往往用保护太大的范围内的资源。例如,一个设计不当程序可以同步对象,而不是每个单独的元件的阵列中的整个阵列(或阵列的甚至一个部分)。

这将意味着一个线程试图读取元件7必须等待线程读或写元件22不必要的。如果同步的粒度是在元件级而不是在阵列级,这两个线程不会互相干扰。

只有当两个线程试图访问的相同元件会有资源争用。这就是为什么一般的规则是(当然是受到限制的同步的数量)仅保护尽可能小的资源成为可能。

不过,说实话,没关系这是多么昂贵,如果选择是由于两个线程争夺一个单一的资源数据损坏。正确地编写应用程序,只担心性能问题,如果当他们出现(“得到它第一次工作的然后的得到它的工作速度快”是我最喜欢的口头禅)。

文章在IBM实际上总结非常漂亮的要点的过后面的同步。

  

由于涉及高速缓存刷新和无效的规则,在Java语言中的同步块通常比通过许多平台提供的关键部分的设施,其通常用原子实现的“测试和设置位”机器指令更昂贵。即使当一个程序只包含在单个处理器上运行的单个线程,同步方法调用仍比非同步的方法调用慢。如果同步实际上需要争用锁,性能损失是显着更大的,因为会有需要几个线程切换和系统调用。

其他的答案给予技术上的细节,我不会试图复制的良好水平。

我将做什么是建议你检查物品的日期(以及作者的隐含能力和意识)。同步在Java中的在早期的JVM非常慢。然而,它的最近提高了很多,这样竞争的同步是快了很多比你想象的,而竞争的同步有太多的改善。

你要知道,这个问题可能并不重要 - 如果你需要同步,以确保正确性,您需要同步,以确保正确性。唯一的时候,我可以看到速度是一个问题是,如果你正在考虑创建一个无锁的实现,而不是(使用非常高效而复杂的 java.util.concurrent.locks.AbstractQueuedSynchronizer中),或使用您的任务,而不是另一种语言也许考虑。

在一般我认为最好的结论是,同步通常是足够快,以在第一次迭代使用。如同所有的性能问题,代码清晰性和正确性,在第一,那么只有优化你衡量是你的应用程序的一个昂贵的部分内容。典型地,这将不会是同步的开销*。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top