Spring 多线程

Spring 通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可以实现一个基于线程池的TaskExecutor。而实际上开发中的任务一般是非阻塞的,即异步的,所以我们要在配置类中通过@EnableAsync注解来开启对异步任务的支持,并通过在实际执行的Bean的方法上使用@Async注解来声明一个异步任务。


配置类:

package com.chenfeng.xiaolyuh.thread.config;

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

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration // 声明当前类是一个配置类,相当于Spring配置的XML文件
@ComponentScan(basePackages={"com.chenfeng.xiaolyuh.thread"})
@EnableAsync// 利用@EnableAsync注解开启异步任务的支持
// 配置类实现AsyncConfigurer接口并重写getAsyncExecutor方法,并返回ThreadPoolTaskExecutor,这样我们就获得了一个基于线程池TaskExecutor
public class ThreadConfig implements AsyncConfigurer {

	@Override
	public Executor getAsyncExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		// 核心线程数 
		taskExecutor.setCorePoolSize(5); 
		// 最大线程数
		taskExecutor.setMaxPoolSize(50); 
		// 队列最大长度
		taskExecutor.setQueueCapacity(1000);
		// 线程池维护线程所允许的空闲时间(单位秒)
		taskExecutor.setKeepAliveSeconds(120);
		// 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
		taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
		
		taskExecutor.initialize();
		return taskExecutor;
	}

	@Bean
	public Executor getThreadPool() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(5);
		taskExecutor.setMaxPoolSize(1000);
		taskExecutor.setQueueCapacity(1000);
		taskExecutor.initialize();
		return taskExecutor;
	}

	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return null;
	}
		
}


任务执行类:

package com.chenfeng.xiaolyuh.thread.service;

import java.util.concurrent.Executor;

import javax.annotation.Resource;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * 多线程的测试类
 * @ClassName DemoELService
 * @author yuhao.wang
 * @Date 2017年3月10日 下午3:41:18
 * @version 1.0.0
 */
@Service
public class DemoThreadService {
	
	@Resource(name = "getThreadPool")
	private Executor executor;
	
	@Async
	// 通过@Async注解方法表名这个方法是一个异步方法,如果注解在类级别,则表名该类的所有方法都是异步的,
	// 而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
	public void executeAsyncTask(Integer i) {
		System.out.println("执行异步任务:" + i);
	}
	
	public void executeAsyncTaskPlus(Integer i) {
		executor.execute(new Runnable() {
			@Override
			public void run() {
				System.out.println("执行异步任务+1:" + i);
			}
		});
	}
}

测试方法:

package com.chenfeng.xiaolyuh.test;

import org.junit.After;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.chenfeng.xiaolyuh.thread.config.ThreadConfig;
import com.chenfeng.xiaolyuh.thread.service.DemoThreadService;

/**
 * Created by yuhao.wang on 2017/3/9.
 */
public class SpringThreadTest {
	AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ThreadConfig.class);

	@Test
	public void contextTest() {
		DemoThreadService demoThreadService = context.getBean(DemoThreadService.class);
		for (int i = 0; i < 1000; i++) {
			demoThreadService.executeAsyncTaskPlus(i);
			demoThreadService.executeAsyncTask(i);
		}
	}

	@After
	public void closeContext() {
		context.close();
	}

}

ThreadPoolTaskExecutor相关知识: http://www.cnblogs.com/lic309/p/4186880.html

ThreadPoolExecutor 相关知识:http://blog.csdn.net/wenhuayuzhihui/article/details/51377174

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值