让Java线程池实现任务阻塞执行的一种可行方案

摘要:
Java的线程池一般是基于concurrent包下的ThreadPoolExecutor类实现的,不过当我们基于spring框架开发程序时,通常会使用其包装类ThreadPoolTaskExecutor,这里有一个小问题就是当使用线程池执行任务的时候,任务的消费速度小于生产速度时,任务通常会被阻塞到阻塞队列,而阻塞队列大小通常是固定的,当阻塞队列满的时候,execute方法并不会阻塞,默认是使用R

Java的线程池一般是基于concurrent包下的ThreadPoolExecutor类实现的,

不过当我们基于spring框架开发程序时,

通常会使用其包装类ThreadPoolTaskExecutor,

这里有一个小问题就是当使用线程池执行任务的时候,

任务的消费速度小于生产速度时,任务通常会被阻塞到阻塞队列,

而阻塞队列大小通常是固定的,当阻塞队列满的时候,execute方法并不会阻塞,

默认是使用RejectedExecutionHandler去处理拒绝的任务,默认策略是AbortPolicy,直接抛出RejectedExecutionException异常,

很多情况下,这不符合我们的业务需求,我们希望被拒绝的任务能够阻塞执行,从而阻止任务的生产速度;

一个比较巧妙的解决方案如下,仅供参考,具体还需要根据实际场景来应用:

importjava.util.concurrent.Executor;
importjava.util.concurrent.ThreadPoolExecutor;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
public classTaskExecutorConfig {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Bean("vgcThreadPoolTaskExecutor")
    publicExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = newThreadPoolTaskExecutor();
        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();
        returntaskExecutor;
    }
}

这里之所以能实现阻塞,是基于BlockingQueue的put方法来实现的,当阻塞队列满时,put方法会一直等待...

免责声明:文章转载自《让Java线程池实现任务阻塞执行的一种可行方案》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇单点登陆 ---密钥/proc/kcore下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python之线程与线程池

# 进程是资源分配的最小单位,线程是CPU调度的最小单位.每一个进程中至少有一个线程。 # 传统的不确切使用线程的程序称为只含有一个线程或单线程程序,而可以使用线程的程序被称为多线程程序,在程序中使用一个线程的方法 # 被称为多线程 # 线程的模块: # thread >> 实现线程的低级接口 # threading>>>...

delphi 自我删除和线程池(1000行代码,需要仔细研究)

[delphi]view plaincopy unitUnit4; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms, Dialogs,StdCtrls,ShellAPI,ShlObj,uThreadPool; type TF...

RPC

背景:公司提供给第三方的数据传输接口一直是以Hessian的协议进行发布的,但是由于交通车辆通行数据量较大,导致第三方反应出现数据延迟的情况或者连接超时的情况,所以需要更换Hessian,换成性能更高的Thrift协议 区别: Hessian  Thrift 优点 1、简单易用,面向接口,通过接口暴露服务,jar包只有200、300k,不需要配置...

异步线程池的实现(一)-------具体实现方法

本篇是这个内容的第一篇,主要是写:遇到的问题,和自己摸索实现的方法。后面还会有一篇是总结性地写线程池的相关内容(偏理论的)。 一、背景介绍     朋友的项目开发到一定程度之后,又遇到了一些问题:在某些流程中的一些节点,由于是串联执行的。上一步要等下一步执行完毕;或者提交数据之后要等待后台其他系统处理完成之后,才能返回结果。这样就会导致,请求发起方不得不一...

心有 netty 一点通!

一、标准的netty线程模型 双池合璧: 1、连接线程池: 连接线程池专门负责监听客户端连接请求,并完成连接的建立(包括诸如握手、安全认证等过程)。 连接的建立本身是一个极其复杂、损耗性能的过程,此处使用线程池,能够极大的增加处理客户端连接的能力。 2、I/O线程池: 连接线程池会将成功建立的连接注册到后端I/O线程池,由I/O线程池负责对相应连接的网络...

Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

     声明:本文为原创博文,转载请注明出处。      Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们。在网络编程中,一般都是基于Reactor线程模型的变种,无论其怎么演化,其核心组件都包含了Reactor实例(提供事件注册、注销、通知功能)、多路复用器(由操作系统提供,比如kque...