JavaスレッドプールThreadPoolExecutor(中)-ユースケースとテスト

スレッドプールメソッドの表示:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
long keepAliveTime, TimeUnit unit, 
BlockingQueue workQueue, 
RejectedExecutionHandler handler) 

コード例:

package tech.summary.demotest.testthreadpool;

import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool2 {
    
    

  public static void main(String[] args) {
    
    
    // 构造一个线程池
    ThreadPoolExecutor threadPool =
        new ThreadPoolExecutor(8, 8, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2),
            new ThreadPoolExecutor.CallerRunsPolicy());

    for (int i = 1; i <= 11; i++) {
    
    
      try {
    
    
        // 产生一个任务,并将其加入到线程池
        String task = "task@ " + i;
        //System.out.println("put " + task);
        threadPool.execute(new ThreadPoolTask2(task));
      } catch (Exception e) {
    
    
        e.printStackTrace();
      }
    }
  }
}

/**
 * 线程池执行的任务
 */
class ThreadPoolTask2 implements Runnable, Serializable {
    
    
  // 保存任务所需要的数据
  private Object threadPoolTaskData;

  ThreadPoolTask2(Object tasks) {
    
    
    this.threadPoolTaskData = tasks;
  }

  @Override
  public void run() {
    
    
    synchronized (this){
    
    
      try {
    
    
        System.out.println(Thread.currentThread().getName()+":"+threadPoolTaskData);
        //this.wait();
        // //便于观察,等待一段时间
        Thread.sleep(15000);
      } catch (Exception e) {
    
    
        e.printStackTrace();
      }
      threadPoolTaskData = null;
    }
  }
}

corePoolSize + workQueue.size()<forループの実行数およびmaximumPoolSize <forループの実行数の場合、メインスレッドが役立ちます

結果の例:

pool-1-thread-1:task@ 1
pool-1-thread-4:task@ 4
pool-1-thread-5:task@ 5
pool-1-thread-3:task@ 3
pool-1-thread-2:task@ 2
pool-1-thread-6:task@ 6
pool-1-thread-7:task@ 7
pool-1-thread-8:task@ 8
main:task@ 11
pool-1-thread-2:task@ 9
pool-1-thread-7:task@ 10

execute(Runnable)メソッドを介してタスクをスレッドプールに追加する場合:

  1. この時点でスレッドプールの数がcorePoolSize未満の場合、スレッドプールのスレッドがアイドル状態であっても、追加されたタスクを処理するために新しいスレッドを作成する必要があります。
  2. この時点でスレッドプールの数がcorePoolSizeと等しいが、バッファーキューworkQueueがいっぱいでない場合、タスクはバッファーキューに入れられます。
  3. この時点でスレッドプールの数がcorePoolSizeより大きい場合、バッファーキューworkQueueがいっぱいであり、スレッドプールの数がmaximumPoolSizeより小さい場合は、追加されたタスクを処理するための新しいスレッドを作成します。
  4. スレッドプール内の数がcorePoolSizeより大きい場合、バッファーキューworkQueueがいっぱいであり、スレッドプール内の数がmaximumPoolSizeに等しい場合、タスクはハンドラーによって指定された戦略によって処理されます。

テスト補足:

  • corePoolSize + workQueue.size()はmaximumPoolSizeより大きくすることができます
  • corePoolSizeがいっぱいになると、workQueueが最初にいっぱいになり、workQueueがいっぱいになると、新しいスレッドがmaximumPoolSizeをいっぱいにします。
  • スレッドの最大数:corePoolSize +スレッドが追加されましたnew = maximumPoolSize
  • 実行中のスレッドがアイドル状態になると、タスクは徐々にworkQueueから解放され、実行用に生成されたアイドル状態のスレッドに入れられます。つまり、workQueue内のタスクの実行が最も遅くなります。
  • スレッドのタスクが完了すると、キャッシュ内のタスクがworkQueueのキャッシュからフェッチされます------ poll()、設定された時間を超えた場合------ keepAliveTimeは、タスク、キューはnullを返し、スレッドはそれ自体を閉じます。

おすすめ

転載: blog.csdn.net/nikyae/article/details/111148902