基于源码简单学习一下Spring线程池

1. Spring线程池的用法

1.1 通过xml配置的方法

<bean id="taskExecutor"
		class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
		<!-- 线程池维护线程的最少数量 -->
		<property name="corePoolSize" value="8" />
		<!-- 线程池维护线程所允许的空闲时间 -->
		<property name="keepAliveSeconds" value="300" />
		<!-- 线程池维护线程的最大数量 -->
		<property name="maxPoolSize" value="16" />
		<!-- 线程池所使用的缓冲队列 -->
		<property name="queueCapacity" value="1000" />
		<!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
		<property name="rejectedExecutionHandler">
			<bean class="java.util.concurrent.ThreadPoolExecutor$AbortPolicy" />
		</property>
	</bean>

1.2 通过代码配置的方式

 @Bean(name = "taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
        //线程池维护线程的最少数量
        poolTaskExecutor.setCorePoolSize(8);
        //线程池维护线程所允许的空闲时间
        poolTaskExecutor.setKeepAliveSeconds(300);
        //线程池维护线程的最大数量
        poolTaskExecutor.setMaxPoolSize(16);
        //线程池所使用的缓冲队列
        poolTaskExecutor.setQueueCapacity(1000);
        //配置拒绝策略
        poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return poolTaskExecutor;
    }

1.3 使用方式简单分析

通过上面的使用方式可以看出,主要有这几个参数:

  • corePoolSize: 核心线程数,线程池中活着的最小的线程数量
  • maxPoolSize:最大线程数,即线程池中最大的线程数量
  • keepAliveSeconds:超过核心线程数的时候,空闲的线程允许等待的最长时间,单位秒
  • queueCapacity: 队列容量,用于存放等待中的任务的队列容量
  • rejectedExecutionHandler:线程池拒绝策略,当队列满了之后,以哪种方式处理新的任务

1.4 如果只是想简单看一下用法的话,就不用再向下看了


2. ThreadPoolTaskExecutor 结构分析

观察其主要代码发现,spring的线程池,主要是对Java原生线程池的一个封装:

private final Object poolSizeMonitor = new Object();
	private int corePoolSize = 1;
	private int maxPoolSize = Integer.MAX_VALUE;
	private int keepAliveSeconds = 60;
	private boolean allowCoreThreadTimeOut = false;
	private int queueCapacity = Integer.MAX_VALUE;
	// ####### 这里就是Java原生的线程池 #######
	private ThreadPoolExecutor threadPoolExecutor;

所有的线程池相关的主要操作,也都是依赖于原生的Java线程池来实现的!!!!
ThreadPoolTaskExecutor UML 图

  1. 从上面的UML图可以看出,左边主要是spring初始化或者销毁的时候,去初始化线程池一些内容;
  • ExecutorConfigurationSupport :主要实现了借助Spring 实现线程池的初始化和销毁、拒绝策略

其中,拒绝策略也是使用了Java原生的,包括:
AbortPolicy:拒绝任务,并抛出异常
CallerRunsPolicy:交给线程池的调用方来执行
DiscardOldestPolicy: 丢弃队列中,最旧的任务
DiscardPolicy:丢弃当前的任务

  • InitializingBean:通过实现afterPropertiesSet,来实现spring bean初始化的时候,线程池的初始化和销毁
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						public Object run() throws Exception {
							((InitializingBean) bean).afterPropertiesSet();
							return null;
						}
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}				
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

  • DisposableBeanL: spring bean销毁的时候,线程池的销毁
  1. 右边则主要是,定义了线程池的一些主要操作:
  • void execute(Runnable task, long startTimeout);
    单纯的执行任务,没有任何返回结果,也无法获取执行情况
  • Future<?> submit(Runnable task);
    返回一个Future,通过future.get,返回null, 表示结果完成
  • Future submit(Callable task);
    返回一个Future,通过future.get 返回Callable的执行结果,来表示执行完成
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值