2014-01-13 64 views
4

我可以看到ReentrantLock比​​和AtomicInteger快了约50%。为什么与这三种同步方法的执行时间存在差异:​​blocks,ReentrantLockAtomicInteger(或Atomic包中的任何类)。同步vs ReentrantLock vs AtomicInteger执行时间

除了这些之外,还有其他流行的和扩展的同步方法吗?

+3

你究竟是如何得到这些表现数字的?由于JIT和GC,Java中的微代码非常棘手。您可以轻松获得误导性结果。 – Jesper

+0

我认为你的意思是'java.util。并发'包 –

+0

我只是使用'System.nanoTime()',它不是一个详尽的测试,我给的percentajes只是指示性的。 – dabadaba

回答

5

AtomicInteger比硬件上的其他两种同步方法快得多,因为它是无锁的。在CPU为无锁并发提供基本设施的体系结构上,完全采用硬件完成操作,其中关键通常采用单个CPU指令。相比之下,ReentrantLock和​​使用多个指令来执行他们的任务,所以你会看到一些相关的开销。

+0

无锁是什么意思? – dabadaba

+0

@dabadaba这意味着'AtomicInteger'上的操作不会无限期地阻塞其他线程,从而允许线程作为一个组来总是取得一些进展。 – dasblinkenlight

+0

或多或少意味着它不能与其他线程一起工作,但在另一个层次上,在硬件层面上呢? – dabadaba

9

一些因素影响这一点。

  • Java的版本。对于ReentrantLock来说Java 5.0速度要快很多,Java 7并没有太多的争用程度
  • 。同步效果最好(一般情况下锁定)和低争用率。 ReentrantLock在更高的争用率下工作得更好。 YMWV
  • JIT可以做多少优化。 JIT优化以ReentrantLOck不同的方式进行优化。如果这是不可能的,你不会看到优势。
  • 同步是GC免费的行动。 ReentrantLock可以创建垃圾,使其更慢,并根据使用方式触发GC。

AtomicInteger使用相同的原语,锁定使用但忙于等待。 CompareAndSet也称为CompareAndSwap,即它的功能简单得多(并且受到更多限制)

ConcurrentXxxx,CopyOnWriteArrayXxxx集合非常受欢迎。这些提供了并发性,而不需要直接使用锁(在某些情况下根本没有锁)

+0

你的争论是什么意思?你的回答符合ReentrantLock比同步更慢,我在结果中看到了相反的结果,请再次检查我的帖子。或者,也许我误解了你的回应。 – dabadaba

+0

@dabadaba yes有时ReentrantLock速度更快,有时速度更慢。这一切都取决于我上面列出的因素。即使你的CPU架构可以有所作为。我看过一个例子,其中具有相同JVM的相同代码在不同型号的CPU上运行(在PC上,而在另一台笔记本上)运行速度明显不同。 –

+0

@dabadaba争用意味着有多少CPU在同一时间试图使用相同的资源。每个资源只需一个线程即可进行测试。 –

1

我认为你在评估这3个元素进行比较时会犯一个常见的错误。

基本上,当ReentrantLock与同步密钥相比,当您正在同步块时,可以让您更灵活。原子是采用基于CAS(比较和交换)的不同方法来管理并发上下文中的更新的东西。

我建议你阅读一本深入Java平台的并发圣经。

Java Concurrency in Practice - Brian Göetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes & Doug Lea

有一个在其上并发有深入的了解,并知道什么是语言可以为您提供解决并发问题,并采取多线程的特性有很大的区别。

就性能而言,它取决于当前情况。