【问题标题】:Singleton / Static Affects performance of Multi-Threaded Java Application?单例/静态影响多线程 Java 应用程序的性能?
【发布时间】:2013-05-25 16:19:50
【问题描述】:

使用 Singleton / Static 会减慢多线程应用程序(在多核系统上运行)的速度吗? 我正在运行一个在 8 核机器上创建 6 个线程的应用程序。最初在所有线程之间共享一些单例对象。而且我没有得到从单线程模型到多线程模型的预期性能提升。 在此之后,我更改了我的代码,以便没有单例或静态(即尝试不在线程之间共享任何内容)并且我获得了大约 6 倍的性能提升。 有人可以解释一下这种行为吗?

【问题讨论】:

  • 我认为我们需要查看一些代码来回答这个问题。如果你对同步资源有很多争用,多线程对你没有多大帮助,甚至可能伤害你。

标签: java multithreading static singleton multicore


【解决方案1】:
  1. static 绝对与减速无关。事实上,静态字段是所有访问中最快的。

  2. 单例本身也不是问题。你可能有惰性初始化个单例,它们的访问器方法是同步的。在这种情况下,您的代码 ss 只是使用了错误的习语。 static 单例的首选习惯用法是 lazy initialization holder class,它会产生零惩罚并且是完全线程安全的。

  3. 您在单例上调用的方法也可能需要同步。通常,如果我们完全使用可变单例,那是因为我们别无选择,只能使用它们。如果你确实有这样的选择,那么一定要避免单身。

为了获得最佳性能,请遵守以下简单规则:

  1. 尽可能少地共享可变状态。突变需要相互排斥并损害性能;

  2. 尽可能多地共享不可变状态。这将减少 CPU 缓存未命中并提高性能。

【讨论】:

  • 惰性初始化持有者类之前在SO上已经介绍过了,包括示例代码。
  • @AndrewLazarus Everything 已经在 SO 上进行了介绍 :) 无论如何,我可能有自己最喜欢的 LIHC 参考资料,来自马的嘴(见我的链接)。跨度>
  • Marko:感谢您将该链接添加到原始答案中。我只是想让 OP 看到示例代码。
  • @AndrewLazarus 我一直在计划该链接,但想先写出答案然后搜索链接。
  • 谢谢。两个要点:(i)我的单例被急切地初始化(在应用程序的任何地方都没有使用同步)。 (ii) 它的状态较少,因此是不可变的。我怀疑是在多核系统中无法有效实现单例并行的情况。
【解决方案2】:

有很多issues 带有状态单例,但您所描述的听起来更像是单例对象的争用。也就是说,您的速度变慢了,因为您的单例正在同步某些东西。在这种情况下,多线程版本可能不会做同样的事情;也就是说,您可能已经用性能问题换取了race condition。您需要向我们展示您的代码的更多细节以获得更具体的答案。照原样,几乎只是猜测。

顺便说一句,恕我直言,状态less单例最好处理为enum。

【讨论】:

  • 我同意@Andrew - 这听起来像是争用,特别是因为性能提升大约等于您使用的线程数。我认为我们需要查看一些代码,但听起来您使用 synchronized 关键字可能做得过火了
猜你喜欢
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 2018-04-29
  • 2012-03-28
相关资源
最近更新 更多