陷阱 - 太多執行緒使應用程式變慢

許多不熟悉多執行緒的人認為使用執行緒會自動使應用程式更快。事實上,它要複雜得多。但有一點我們可以肯定地說,對於任何計算機,可以同時執行的執行緒數量有限制:

  • 計算機具有固定數量的核心 (或超執行緒 )。
  • 必須將 Java 執行緒排程到核心或超執行緒才能執行。
  • 如果有比可用的核心/超執行緒更多的可執行 Java 執行緒,則其中一些必須等待。

這告訴我們,簡單地建立越來越多的 Java 執行緒無法使應用程式變得越來越快。但是還有其他一些考慮因素:

  • 每個執行緒都需要一個用於其執行緒堆疊的堆外記憶體區域。典型(預設)執行緒堆疊大小為 512K 位元組或 1M 位元組。如果你有大量執行緒,則記憶體使用量可能很大。

  • 每個活動執行緒將引用堆中的許多物件。這增加了可到達物件的工作集,這會影響垃圾收集和實體記憶體使用。

  • 執行緒之間切換的開銷非常重要。它通常需要切換到 OS 核心空間以進行執行緒排程決策。

  • 執行緒同步和執行緒間信令(例如 wait(),notify()/ notifyAll)的開銷可能很大。

根據應用程式的詳細資訊,這些因素通常意味著執行緒數量存在最佳位置。除此之外,新增更多執行緒可以最大限度地提高效能,並且可以使效能變差。

如果你的應用程式為每個新任務建立,那麼工作負載的意外增加(例如,高請求率)可能導致災難性行為。

處理此問題的更好方法是使用有界執行緒池,其大小可以控制(靜態或動態)。當有太多工作要做時,應用程式需要對請求進行排隊。如果使用 ExecutorService,它將負責執行緒池管理和任務排隊。