Java thread pool ThreadPoolExecutor (medium)-use cases and tests

Thread pool method display:

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

Code example:

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;
    }
  }
}

When corePoolSize+workQueue.size()<the number of for loop execute, and maximumPoolSize<the number of for loop execute, the main thread will come out to help

Example result:

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

When a task is to be added to the thread pool through the execute(Runnable) method:

  1. If the number in the thread pool is less than corePoolSize at this time, even if the threads in the thread pool are idle, a new thread must be created to handle the added task.
  2. If the number of thread pools is equal to corePoolSize at this time, but the buffer queue workQueue is not full, then the task is put into the buffer queue.
  3. If the number in the thread pool is greater than corePoolSize at this time, the buffer queue workQueue is full, and the number in the thread pool is less than the maximumPoolSize, a new thread is created to process the added tasks.
  4. If the number in the thread pool is greater than corePoolSize, the buffer queue workQueue is full, and the number in the thread pool is equal to the maximumPoolSize, then the task is processed by the strategy specified by the handler.

Test supplement:

  • corePoolSize+workQueue.size() can be greater than maximumPoolSize
  • When the corePoolSize is full, the workQueue is filled first, and when the workQueue is full, the new thread fills the maximumPoolSize
  • Maximum number of threads: corePoolSize+ threads added new = maximumPoolSize
  • When the executing thread is idle, the tasks are gradually released from the workQueue and put into the idle threads that have been generated for execution, that is to say, the tasks in the workQueue are the slowest to execute.
  • When the task of a thread is completed, the task in the cache will be fetched from the cache of the workQueue ------ poll(), if it exceeds the set time ------ keepAliveTime has not fetched the task, The queue returns null and the thread closes itself.

Guess you like

Origin blog.csdn.net/nikyae/article/details/111148902