A feasible solution to let Java thread pool realize task blocking execution

Java's thread pool is generally implemented based on the ThreadPoolExecutor class under the concurrent package.

However, when we develop programs based on the spring framework,

Usually its wrapper class ThreadPoolTaskExecutor is used,

There is a small problem here that when using the thread pool to perform tasks,

When the consumption speed of the task is less than the production speed, the task is usually blocked to the blocking queue,

The blocking queue size is usually fixed. When the blocking queue is full, the execute method will not block.

The default is to use RejectedExecutionHandler to handle rejected tasks. The default policy is AbortPolicy, which throws RejectedExecutionException directly.

In many cases, this does not meet our business needs, and we want rejected tasks to block execution, thereby preventing the production speed of tasks;

A more ingenious solution is as follows, which is for reference only, and needs to be applied according to the actual scene:

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;


@Configuration
public class TaskExecutorConfig {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Bean("vgcThreadPoolTaskExecutor")
    public Executor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(6);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(1000);
        taskExecutor.setRejectedExecutionHandler((Runnable r, ThreadPoolExecutor executor) -> {
                    if (!executor.isShutdown()) {
                        try {
                            executor.getQueue().put(r);
                        } catch (InterruptedException e) {
                            logger.error(e.toString(), e);
                            Thread.currentThread().interrupt();
                        }
                    }
                }
        );
        taskExecutor.initialize();
        return taskExecutor;
    }


}

The reason why blocking can be achieved here is based on the put method of BlockingQueue. When the blocking queue is full, the put method will always wait...

Guess you like

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