Java Concurrent Programming Diary - Thread Pool Introduction and Usage Suggestions

There are four kinds of thread pools in JDK, namely FixedThreadPool , SingleThreadExecutor , CachedThreadPool , ScheduledThreadPool , they all depend on a core class ThreadPoolExecutor

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}
  • corePoolSize : The number of threads in the pool remains, even if these applications are idle, unless the core thread time is set
  • maximumPoolSize : the maximum number allowed in the thread pool
  • keepAliveTime : When the number of threads is greater than the number of core threads, the maximum time that idle threads will wait for new tasks before terminating. Once this time is exceeded, idle threads will be recycled until the number of threads is equal to the number of core threads
  • unit : the time unit of keepAliveTime
  • workQueue : The queue is used before tasks are executed. This queue only holds Runnable tasks submitted by the execute method

FixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

FixedThreadPool is a thread pool with a fixed number of threads. The core thread is equal to the maximum number of threads. The idle threads that exceed the number of core threads are recycled immediately. The task queue uses LinkedBlockingQueue , and the size of LinkedBlockingQueue is Integer.MAX_VALUE.

SingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

SingleThreadExecutor is a thread pool with a single number of threads. The number of core threads and the maximum number of threads is equal to 1. The idle threads that exceed the number of core threads are immediately recycled. The task queue uses LinkedBlockingQueue , and the size of LinkedBlockingQueue is Integer.MAX_VALUE.

CachedThreadPool

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

CachedThreadPool is a thread pool that caches the number of threads. The core thread is 0, and the maximum number of threads is Integer.MAX_VALUE. Threads that are idle for more than 60 seconds will be recycled. The task queue uses SynchronousQueue . SynchronousQueue is the work queue of the main thread pool. It is a blocking queue with no capacity. Each insert operation must wait for a corresponding remove operation by another thread. This means that the CachedThreadPool will keep creating new threads if the main thread is submitting tasks faster than the thread pool can process them.

ScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}

ScheduledThreadPool is a thread pool for executing timed tasks. The core thread is the incoming value. The maximum number of threads is equal to Integer.MAX_VALUE. The idle threads that exceed the number of core threads are recycled immediately. The task queue uses DelayedWorkQueue . DelayedWorkQueue implements the interface of LinkedBlockingQueue and its size is Integer.MAX_VALUE.


In daily development, it is not recommended to directly use Executors to directly create the above thread pools, but to create the disadvantages of each method of Executors through explicit ScheduledThreadPoolExecutor :
1. newFixedThreadPool and newSingleThreadPool :
The main problem is that the accumulated request processing queue may be It will consume a very large amount of memory, even OOM.
2. The main problem of newCachedThreadPool and newScheduledThreadPool
is that the maximum number of threads is Integer.MAX_VALUE, and there may be a very large number of threads, even OOM

The recommended method to use is to create

    ExecutorService pool = new ThreadPoolExecutor(5,200,
            0L,TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

When the task exceeds the size of the queue, some strategy of rejecting needs to be implemented

  • CallerRunsPolicy : continue execution as long as the current thread is not closed
  • AbortPolicy : Throw RejectedExecutionException directly with thread information
  • DiscardPolicy : just throw this task away
  • DiscardOldestPolicy : throw away the oldest and execute the newly added

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325937932&siteId=291194637