Spring 多线程

来源:互联网 发布:新型网络创业 编辑:程序博客网 时间:2024/04/30 07:16

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,这样我们就获得了一个基于线程池TaskExecutorpublic class ThreadConfig implements AsyncConfigurer {@Overridepublic 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;}@Beanpublic Executor getThreadPool() {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();taskExecutor.setCorePoolSize(5);taskExecutor.setMaxPoolSize(1000);taskExecutor.setQueueCapacity(1000);taskExecutor.initialize();return taskExecutor;}@Overridepublic 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 */@Servicepublic class DemoThreadService {@Resource(name = "getThreadPool")private Executor executor;@Async// 通过@Async注解方法表名这个方法是一个异步方法,如果注解在类级别,则表名该类的所有方法都是异步的,// 而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutorpublic void executeAsyncTask(Integer i) {System.out.println("执行异步任务:" + i);}public void executeAsyncTaskPlus(Integer i) {executor.execute(new Runnable() {@Overridepublic 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);@Testpublic void contextTest() {DemoThreadService demoThreadService = context.getBean(DemoThreadService.class);for (int i = 0; i < 1000; i++) {demoThreadService.executeAsyncTaskPlus(i);demoThreadService.executeAsyncTask(i);}}@Afterpublic void closeContext() {context.close();}}

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

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

0 0
原创粉丝点击