【问题标题】:Java Multithreading QuestionsJava 多线程问题
【发布时间】:2016-06-23 00:54:03
【问题描述】:

1):单线程应用程序在用户的 CPU 上是否只使用 1 个线程?提供更多线程会使用多个 CPU 内核吗?如果您声明的线程数超过了用户 CPU 的数量会怎样?

2):只要您的方法不存在同步问题或其他问题,为您的每个方法创建新线程是否会影响性能?

3):我在做游戏,偶尔收垃圾的时候会有明显的卡顿。将垃圾收集器放在自己的线程中会解决这个问题吗?

【问题讨论】:

  • 垃圾收集器确实在它自己的线程(或多个线程)中运行。尽管所有 GC 实现都有一个“停止世界”的时刻,但调整 GC 可以产生巨大的影响。 (首先创建更少的垃圾也有帮助。:))这也回答了第一个问题:不,即使是“单线程”Java 应用程序也会有多个线程在运行。
  • 但我看到的主要问题是您认为使用多线程是解决性能问题的方法。事实上,这种情况很少发生,并且在一个问题上投入越来越多的线程会很快开始降低您的性能。
  • 别叫System.gc();一堆,那样会导致性能问题,让java自己做吧。
  • 我知道不要经常调用它,但我注意到了口吃,所以为了测试它我绑定了 System.gc();到一个键,当我按下它时,果然有口吃。

标签: java multithreading performance


【解决方案1】:

您提出的问题:

  1. 是的,一个线程意味着一个 CPU 线程。额外的线程可以使用额外的 CPU,只要它们有工作要做。如果创建的线程多于 CPU,它们会争夺 CPU 时间,结果通常会变慢。一些 CPU 使用超线程并暴露出比实际内核更多的线程(有时这会带来性能优势)。使用Runtime.getRuntime.availableProcessors() 显示建议的线程数。
  2. 是的,创建和销毁线程并不便宜,还有一个large overhead for each thread。出于这个原因,池化和重用线程是一种极其常见的模式。不要为每个方法调用创建一个线程。
  3. 垃圾收集器已经在单独的线程中完成它的工作,但它必须在至少部分 GC 中导致“停止世界”暂停,以便标记死对象以进行收集。

你需要的问题和答案,你没有问的问题:

问:我怎样才能让它更快?

答:几种方式:

  • 简介:找出程序中的瓶颈所在,并专注于此。 10% 的代码通常会占用 90% 的运行时间。
  • 在尝试优化实现之前,请关注算法。唯一比以 2 倍速度执行昂贵操作更好的是永远不必这样做。延迟加载和缓存结果可以节省大量时间。
  • 使用一个主线程进行渲染和用户交互,并尽可能少做实际工作。这使系统看起来对用户有响应。渲染应该只在发生变化时创建新对象。
  • 将工作队列和工作线程池用于长时间运行的任务尤其是网络请求或磁盘 I/O,这会阻塞渲染和 UI 线程。您所有的实际工作都应该是异步的。
  • 尽可能少地产生垃圾——不要在不需要的时候制造和销毁对象。垃圾收集应该很少成为 Java 程序的重大瓶颈。
  • 单个线程用于磁盘 I/O,池中的多个线程用于网络 I/O,每个 CPU 使用一个工作线程。

编辑:在有人抱怨之前,异步 I/O 或非阻塞 I/O 在网络请求方面比线程池执行得更好,但对于新开发人员来说,正确使用它们也更复杂。只要您不编写繁重的网络内容,一个中等大小的线程池就足以使网络连接饱和,尽管存在延迟。

如果您收到明显的垃圾回收暂停,那么您可能做错了什么。垃圾收集经过优化,可以在最短的时间内获得最多的结果。大多数时候,GC 暂停将是几毫秒来执行一次次要 GC(除非我们谈论的是 4+ GB 的堆)。 不要显式调用 System.gc() 否则你会强制执行不必要的工作和暂停。

【讨论】:

  • 太棒了!这些将是我的下一个问题!
  • @MitchWeaver 这几乎就像我以前遇到过这个问题;)
【解决方案2】:

1) 您的应用程序可能只使用 1 个线程,此外 JVM 可能会创建自己的线程(例如,垃圾收集在其自己的线程(或更多)中分离出来)。更多的线程使用更多的 CPU,如果你的线程比 CPU 多,调度程序会让线程轮流运行(上下文切换)。

2) 过多的上下文切换(调度程序必须在您创建的所有线程之间来回切换并让它们有机会运行)和耗尽操作系统线程(要么创建太多线程,要么由于它们而丢失它们他们永远不会完成任务)会导致性能问题。

3) 垃圾收集器已经在它自己的线程(或多个线程)中。调整 GC 和避免产生过多垃圾都是不错的技巧。

请参阅Amdahl's Law,了解线程可以加速任务的限制。 您从问题中排除了锁定,但过度锁定是性能的主要障碍。

【讨论】:

  • 过多的上下文切换也会导致性能问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 2016-12-12
  • 2011-09-11
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多