Detailed explanation of the implementation of the rejection policy of java thread pool

1、 Introduction

jdk1. Version 5 adds JUC concurrent programming package, which greatly simplifies the traditional multithreading development.

Java thread pool is the product of typical pooling ideas, such as database connection pool and redis connection pool. The idea of pooling is to apply for resources and create a batch of usable connections at the beginning, so that there is no need to create connection information at the time of use. For example, when you go to a famous foreign fast food base or labor, the catering staff takes bytes directly from a middle incubator and then packs them. There is no need to temporarily come up with a list. We have to get raw materials and process them. The efficiency is obviously improved a lot.

Since it is a pool, there must be attributes such as maximum value, initial value and survival value. How does the pool process requests when certain conditions are met? This leads to the rejection policy of the pool. When the database connection pool reaches the maximum number of connections, it will wait for a specific set time by default or throw an exception directly. The thread pool to be described in this article is not such a strategy. Let's start to explain it.

2、 Reject policy for thread pool

In the thread pool, there are three important parameters that determine the rejection policy: corepoolsize - the number of core threads, that is, the minimum number of threads. Workqueue - block the queue. Maximumpoolsize - maximum number of threads

When the number of submitted tasks is greater than the corepoolsize, priority will be given to placing the tasks in the workqueue blocking queue. When the blocking queue is saturated, the number of threads in the thread pool will be expanded until it reaches the maximum poolsize configuration. At this time, if there are more redundant tasks, the rejection policy of the thread pool will be triggered.

To sum up, in a word, when the number of tasks submitted is greater than (workqueue. Size() + maximumpoolsize), the rejection policy of the thread pool will be triggered.

3、 Reject policy definition

The rejection policy provides a top-level interface rejectedexecutionhandler, in which the method rejectedexecution is to customize the execution logic of the specific rejection policy.

JDK provides four rejection policies by default: callerrunspolicy - when the rejection policy is triggered, as long as the thread pool is not closed, the calling thread is used to run the task directly.

Generally, concurrency is relatively small, performance requirements are not high, and failure is not allowed. However, because the caller runs the task himself, if the task submission speed is too fast, it may lead to program blocking and inevitable loss of performance and efficiency

Abortpolicy - discards the task and throws an exception rejecting the execution of rejectedexecutionexception. Thread pool default reject policy. The exceptions thrown must be handled properly, otherwise the current execution process will be interrupted and subsequent task execution will be affected.

Discardpolicy - discard directly, nothing else

Discardoldestpolicy - when the reject policy is triggered, as long as the thread pool is not closed, discard the oldest task in the blocking queue workqueue and add a new task

4、 Test code

1、AbortPolicy

package com.cfang;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class T2 {
 public static void main(String[] args) throws Exception{
  int corePoolSize = 5;
  int maximumPoolSize = 10;
  long keepAliveTime = 5;
  BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
  RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
  ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.SECONDS,workQueue,handler);
  for(int i=0; i<100; i++) {
   try {
    executor.execute(new Thread(() -> log.info(Thread.currentThread().getName() + " is running")));
   } catch (Exception e) {
    log.error(e.getMessage());
   }
  }
  executor.shutdown();
 }
}

If the executor Execute() submits the task. Because runtimeException will be thrown, if the exception information is not handled by try.catch, the processing flow of the caller will be interrupted, and the subsequent tasks will not be executed (more than 100 runs). You can test it yourself.

2、CallerRunsPolicy

The subject code is the same as above, and the replacement rejection policy:

RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

After running, what you can see in the console console is that some data will be printed and "main is running" will be displayed, which reflects the calling thread processing.

3、DiscardPolicy

Replace reject policy

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

Discard the task directly. In actual operation, there will be no 100 printed messages.

4、DiscardOldestPolicy

Similarly, replace the reject policy:

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();

In actual operation, the printed information will be less than 100.

5、 Summary

The four rejection strategies are independent of each other. The choice of which strategy to implement must be combined with specific business scenarios. In practice, when executorservice is directly used, the default defaulthandler, that is, abortpolicy policy policy, is used.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>