なぜアリババjava開発マニュアルではアプリケーションでスレッドを明示的に作成できないのか


『java開発マニュアル(泰山版)』を読むと、同時処理スレッドプールに関する2つの使用規約が発見され、具体的な内容は以下の通りである.
  • 【強制】スレッドリソースは、アプリケーション内でスレッドを明示的に作成できないスレッドプールを介して提供する必要があります.説明:スレッドプールの利点は、スレッドの作成と破棄にかかる時間とシステムリソースのオーバーヘッドを削減し、リソース不足の問題を解決することです.スレッドプールを使用しない場合、システムが大量の同類スレッドを作成し、メモリを消費したり、「過剰な切り替え」をしたりする可能性があります.
  • 【強制】スレッドプールはExecutorsを使用して作成することを許さず、ThreadPoolExecutorの方式を通じて、このような処理方式は書く学生にスレッドプールの運行規則をより明確にさせ、資源が枯渇するリスクを回避させる.説明:Executorsが返すスレッドプールオブジェクトの弊害は以下の通りである:1)FixedThreadPoolとSingleThreadPool:許可された要求キュー長はIntegerである.MAX_VALUEでは、大量のリクエストが蓄積され、OOMが発生する可能性があります.2)CachedThreadPool:作成できるスレッドの数はInteger.MAX_VALUEでは、大量のスレッドが作成され、OOMが発生する可能性があります.

  • 上記の第1条の規則について、その中ですでにこのようにする原因を説明して、それは上述の原因のほかに、《コードが効率的です》の本の中でまたいくつかのその他の説明に言及しました:
  • スレッドプールを利用してスレッドを管理し多重化し、最大同時数を制御する.
  • タスクスレッドキューキャッシュポリシーと拒否メカニズムを実装します.
  • は、タイミング実行、サイクル実行など、時間に関連するいくつかの機能を実現する.
  • スレッド環境を分離します.例えば、取引サービスと検索サービスは同じサーバー上で、それぞれ2つのスレッドプールを開き、取引スレッドの資源消費は明らかに大きい.したがって、独立したスレッドプールを構成することで、遅いトランザクションサービスと検索サービスを分離し、サービススレッドが相互に影響しないようにします.

  • 「コードアウト効率」のほか、「java同時プログラミング実戦」では、いくつかの因数を見つけることができます.
  • スレッドプールの実行フレームワークExecutorは、タスクのコミットを実行ポリシーとデカップリングすることができる.

  • 上記の第2条の規定についても、その理由を説明したが、「コード出力効率」書では詳細に説明している.実は『Java開発マニュアル(詳細版)』では、ScheduledThreadPoolもCachedThreadPoolとの弊害があるとまとめられていますが、『java開発マニュアル(泰山版)』では削除されていますが、なぜか、これは後で検討してもいいです.
    Executorsが返すスレッドプールオブジェクトには、なぜこのような弊害があるのでしょうか.Executorsの4つのスレッドプールオブジェクトのソースコードを見てみましょう.
    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
    }
    
    public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
    }
    
    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
    }
    
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
            return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    

    上記のコードから、newFixedThreadPoolとnewSingleThreadExecutorには作業タスクキューの境界が指定されていないことが明らかになり、タスクが積み重なるとOOMになります.一方、newCachedThreadPoolとnewScheduledThreadPoolは、最大スレッド数が指定されていないため、タスクが多い場合に大量のスレッドが作成され、OOMが発生する可能性があります.
    ここでは、AbortPolicy(デフォルト)、DiscardPolicy、DiscardOldestPolicy、CallerRunsPolicyの4つの拒否ポリシーを提供します.
  • AbortPolicy:拒否後に異常を投げ出す
  • DiscardPolicy:廃棄タスク
  • DiscardOldestPolicy:キューの先頭にあるタスクを破棄する
  • CallerRunsPolicy:呼び出しスレッド(タスクをコミットするスレッド)によって処理されるタスク
  • リファレンス
  • java開発マニュアル(泰山版)
  • 『コード出力効率』
  • 『java同時プログラミング実戦』