单线程应用程序中的同步方法是否更慢?

在过去的几分钟里,我一直在为自己辩论,而且我看到了是和否的原因。 这源于查看Java HashMap与Hashtable的答案,并看到有几个人说Hashtable实际上更慢。

在我看来,如果在单个线程中运行,同步方法应该与其非同步方法完全没有区别,因为同步操作不应该阻塞任何内容。 也就是说,我认为编译器会以不同的方式处理这两种情况,这就是人们说同步速度较慢的原因。

并不是说它无论如何都是决定性的,但我对HashMap和Hashtable进行了一些简单的测试,并且看到了速度上的差别。

是的,使用同步的单线程Java程序可能比没有同步时更慢。 对于早期Java版本,同步很昂贵。 但是,对于任何现代版本,无竞争同步都相当便宜。 我不担心这个。

请注意,Java 6和Java 7在锁定方面有很好的优化:

  • 锁定粗化
  • 锁定省略
  • 自适应旋转锁定
  • 有偏见的锁定

有关更多信息,请参阅Java SE 6性能白皮书 。 另请注意,多核CPU上的无竞争同步似乎比单核CPU上更昂贵,这可能是由于Java内存模型要求同步强制本地CPU高速缓存与其他CPU或其他一些内存屏障共享。 例如,阅读Do Do Java 6线程优化实际上有效吗? – 第二部分 。 (第一部分没有第二部分那么富有洞察力。)

是。 由于维护锁的额外开销,它们会稍微慢一些。

使用同步数据结构时,减速不依赖于“阻止多少”。 获取或释放锁定的行为很慢,因为它通常涉及类似系统调用(上下文切换在任何平台上都很慢)。 在像典型JVM这样的JIT环境中,理论上可以在只有一个线程运行时优化掉所有锁定/解锁调用,但只要另一个线程启动就必须正确地使其无效。

请注意,Linux的futexes之类的东西不必进行系统调用,除非存在争用,但使用它们仍然比无操作更慢。