spring bootでjavaスレッド池ExectorServiceを使って説明します。


1.javaスレッド池を知っています。
1.1スレッド池はどのような場合に使いますか?
  • 1.単一タスク処理の時間が短い
  • 2.処理したいタスクの数は
  • です。
    1.2スレッド池を使用するメリット:
  • 1.スレッドの作成と廃棄にかかる時間とシステムリソースのオーバーヘッドを低減する
  • .スレッド池を使用しないと、システムが大量のスレッドを作成し、システムメモリ
  • を消費してしまう恐れがある。
    1.3スレッド池は以下の4つの基本構成部分を含む。
  • 、スレッド池マネージャ(ThreadPool):スレッド池を作成して管理するためのもので、スレッド池を作成すること、スレッドを破壊すること、新しいタスクを追加することなどが含まれる。
  • 、ワークスレッド(PoolWorker):スレッドのプールでは、スレッドは、タスクがないときは待機状態にあり、ループしてタスクを実行することができます。
  • 、タスクインターフェース(Task):各タスクが必ず実行されるインターフェースは、ワークスレッドスケジューリングタスクの実行のために、主にタスクの入口を規定し、タスクが完了した後の終了作業、タスクの実行状態などを規定する。
  • 、タスクキュー:未処理のタスクを保存するために使用されます。バッファ機構を提供します。
  • 1.4スレッド池のコアパラメータ
    ThreadPool Exectorは4つの構造方法があります。最初の3つは最後の呼び出しです。
    
     public ThreadPoolExecutor(int corePoolSize,
                   int maximumPoolSize,
                   long keepAliveTime,
                   TimeUnit unit,
                   BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
           Executors.defaultThreadFactory(), defaultHandler);
      }
      public ThreadPoolExecutor(int corePoolSize,
                   int maximumPoolSize,
                   long keepAliveTime,
                   TimeUnit unit,
                   BlockingQueue<Runnable> workQueue,
                   ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
           threadFactory, defaultHandler);
      }
      public ThreadPoolExecutor(int corePoolSize,
                   int maximumPoolSize,
                   long keepAliveTime,
                   TimeUnit unit,
                   BlockingQueue<Runnable> workQueue,
                   RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
           Executors.defaultThreadFactory(), handler);
      }
      //     
      public ThreadPoolExecutor(//      
      int corePoolSize, 
                   //      
                   int maximumPoolSize, 
                   //         
                   long keepAliveTime, 
                   //     
                   TimeUnit unit, 
                   //     
                   BlockingQueue<Runnable> workQueue, 
                   //      
                   ThreadFactory threadFactory,        
                   //     ,                               
                   RejectedExecutionHandler handler  ) {
        if (corePoolSize < 0 ||
          maximumPoolSize <= 0 ||
          maximumPoolSize < corePoolSize ||
          keepAliveTime < 0)
          throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
          throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
      }
    主なパラメータ
    corePoolSize:コアスレッド数
  • コアスレッドは常に生存しています。ジョブがなくても
  • を実行する必要があります。
  • スレッド数がコアスレッド数より小さい場合、スレッドが空きがあっても、優先的に新しいスレッド処理
  • を作成する。
  • にallowCoreThed Timeout=true(デフォルトfalse)を設定すると、コアスレッドがタイムアウトして
  • を閉じることができます。
    maxPoolSize:最大スレッド数
  • スレッド数>=corePoolSizeで、ジョブキューがいっぱいになったとき。スレッド池は新しいスレッドを作成してタスクを処理します。
  • スレッド数=maxPoolSizeで、ジョブのキューがいっぱいになった場合、スレッド池はジョブの処理を拒否して、異常
  • をスローします。
    keep Alive Time:スレッド空き時間
  • スレッドの空き時間がkeep Alive Timeに達すると、スレッド数=corePoolSize
  • まで終了する。
  • allowCoreThed Timeout=trueの場合、スレッド数=0
  • まで
    workQue:一つのブロック列は、実行待ちのタスクを格納するために使用されています。このパラメータの選択も重要です。スレッドプールの運行過程に大きな影響を与えます。一般的に、ここのブロック列は以下のような選択があります。
  • ArayBlocking Que;
  • Linked Blocking Que;
  • SynchronousQue;
  • 渋滞行列についてはこれを見てもいいです。java閉塞行列
    threadFactory:スレッド工場は主にスレッドを作成するために使われます。
    rejectedExecution Handler:ジョブ拒否プロセッサ、2つの場合は処理タスクを拒否します。
  • スレッド数が既にmaxPoolSizeに達しています。切断列がいっぱいになりました。新しいタスク
  • を拒否します。
  • スレッドがshutdown()に呼び出されると、スレッドの池でのタスクの実行が完了するのを待って、shutdownに戻ります。shutdown()とスレッドプールの本当にshutdown間でタスクを提出すると、新しいタスク
  • を拒否します。
    タスクを拒否すると、スレッド池はrejectedExecution Handlerを呼び出してこのタスクを処理します。デフォルトがAbortPolicyに設定されていないと、異常が発生します。ThreadPool Exector類にはいくつかの内部実装類があります。
  • AbortPolicy廃棄任務、スロー運転時異常
  • CallerRunsPolicy実行タスク
  • DisccardPolicy無視して、何も起こらない
  • DisccardOldest Policyは、最初にキューに入る(最後の実行)ジョブ
  • をキューから蹴り出す。
  • は、RejectedExecution Handlerインターフェースを実現し、カスタムプロセッサ
  • を実行することができる。
    1.5 Javaスレッド池ExectorService
  • Exectors.newCachedThreadPoolはキャッシュ可能なスレッドプールを作成し、スレッドの長さが処理の必要を超えている場合、空きスレッドを柔軟に回収でき、回収できない場合は新しいスレッドを作成する。
  • Exectors.newFixedThreadPoolは、スレッドの最大の同時数を制御し、超えたスレッドはキューの中で待機します。
  • Exectors.newScheduledThreadPoolは定長線のプログラムプールを作成し、タイミングと周期的なタスクの実行をサポートします。
  • Exectors.newSingleThreadExectorは、単一の線程化されたスレッドプールを作成します。これは唯一のワークスレッドでのみタスクを実行し、すべてのタスクが指定された順序(FIFO、LIFO、優先度)で実行されることを保証します。
  • 備考:Exectorsは一つの工場類にすぎません。そのすべての方法はThreadPoolExector、ScheduledThreadPoolExectorの二つの種類の例です。
    1.6 ExectorServiceは以下のいくつかの実行方法があります。
  • exectorService.execute(Runnable)この方法は、Runnableの例を受信し、非同期的に
  • を実行する。
  • exectorService.submit
  • exectorService.submit
  • exector Service.invokeAny(…)
  • exector Service.invokeAll(…)
  • execute(Runnable)
    この方法は、Runnableの例を受信し、非同期的に実行する。
    
    executorService.execute(new Runnable() {
    public void run() {
      System.out.println("Asynchronous task");
    }
    });
    executorService.shutdown();
    submit(Runnable)
    submit(Runnable)とexecute(Runnable)の違いは前者がFutureオブジェクトに戻り、Futureオブジェクトに戻ることで、提出されたジョブの実行が完了したかどうかを確認できます。以下の例を見てください。
    
    Future future = executorService.submit(new Runnable() {
    public void run() {
      System.out.println("Asynchronous task");
    }
    });
    future.get(); //returns null if the task has finished correctly.
    submit(Callable)
    submitはsubmit(Callable)とsubmit(Runnable)と同様に、Futureオブジェクトを返すこともあるが、この他に、submit(Callable)が受信したのはCallableの実現であり、Callableインターフェースのcall(call)方法はリターン値があり、タスクの実行結果に戻ることができます。次の例を見てください。
    
    Future future = executorService.submit(new Callable(){
    public Object call() throws Exception {
      System.out.println("Asynchronous Callable");
      return "Callable Result";
    }
    });
    System.out.println("future.get() = " + future.get());
    ミッションが完了すれば、future.get()メソッドはCallableタスクの実行結果に戻ります。なお、future.get()方法はブロックされます。
    invokeAny(…)
    invokeAny(…)メソッドはCallableのセットを受信し、この方法を実行するとFutureに戻りませんが、全てのCallableタスクのうちの一つのタスクの実行結果を返します。この方法では、どのタスクの実行結果が返ってくるかは保証できません。いずれかです。
    
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Set<Callable<String>> callables = new HashSet<Callable<String>>();
    callables.add(new Callable<String>() {
    public String call() throws Exception {
      return "Task 1";
    }
    });
    callables.add(new Callable<String>() {
    public String call() throws Exception {
      return "Task 2";
    }
    });
    callables.add(new Callable<String>() {
      public String call() throws Exception {
      return "Task 3";
    }
    });
    String result = executorService.invokeAny(callables);
    System.out.println("result = " + result);
    executorService.shutdown();
    invokeAll(…)
    invokeAll(…)もinvokeAny(…)と同様に、Callableのセットを受信したが、前者は実行後にFutureのListに戻り、Callableごとのタスク実行後のFutureオブジェクトに対応する。
    
    List<Future<String>> futures = executorService.invokeAll(callables);
    for(Future<String> future : futures){
    System.out.println("future.get = " + future.get());
    }
    executorService.shutdown();
    2.springBootにjavaスレッド池ExectorServiceを使用する
    2.1 springBootの使用構成
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    /**
     *       ,      Spring         ExecutorService  .
     * @author Bruce
     * @date 2017/2/22
     * update by Cliff at 2027/11/03
     */
    @Configuration
    public class ThreadPoolConfig {
      @Bean
      public ExecutorService getThreadPool(){
        return Executors.newFixedThreadPool();
      }
    }
    2.2使用
    
     @service     ExecutorService          。
      @Autowired
      private ExecutorService executorService;
    public void test(){
        executorService.execute(new Runnable() {
          public void run() {
            System.out.println("Asynchronous task");
          }
        });
      }
    締め括りをつける
    以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考学習価値を持ってほしいです。ありがとうございます。もっと知りたいなら、下のリンクを見てください。