标签:handler sys def art cti 提高 unit 调用 线程
合理使用异步线程开发项目能提高一个项目的并发量,减少响应时间。下面就简单介绍一下异步线程池的使用,参考博客:https://blog.csdn.net/hry2015/article/details/67640534
spring 对@Async定义异步任务的方法有3种:
1.最简单的异步调用,返回值为void;
2.带参数的异步调用,异步方法可以传入参数;
3.异常调用返回Future
代码如下:
package com.hry.spring.async.annotation;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
/**
* 异步方法调用
*
* @author hry
*
*/
@Component
public class AsyncDemo {
private static final Logger log = LoggerFactory.getLogger(AsyncDemo.class);
/**
* 最简单的异步调用,返回值为void
*/
@Async
public void asyncInvokeSimplest() {
log.info("asyncSimplest");
}
/**
* 带参数的异步调用 异步方法可以传入参数
*
* @param s
*/
@Async
public void asyncInvokeWithParameter(String s) {
log.info("asyncInvokeWithParameter, parementer={}", s);
}
/**
* 异常调用返回Future
*
* @param i
* @return
*/
@Async
public Future<String> asyncInvokeReturnFuture(int i) {
log.info("asyncInvokeReturnFuture, parementer={}", i);
Future<String> future;
try {
Thread.sleep(1000 * 1);
future = new AsyncResult<String>("success:" + i);
} catch (InterruptedException e) {
future = new AsyncResult<String>("error");
}
return future;
}
}
spring启动配置的方式有两种:
1.注解;
2.XML配置文件
我们先说注解的方式:
@EnableAsync注解可以开启异步调用功能, public AsyncTaskExecutor taskExecutor() 方法自定义自己的线程池,线程池前缀”Anno-Executor”。如果不定义,则使用系统默认的线程池。代码如下:
package com.hry.spring.async.annotation;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* 通过@EnableAsync启动异步方法
* @author hry
*
*/
@SpringBootApplication
@EnableAsync // 启动异步调用
public class AsyncApplicationWithAnnotation {
private static final Logger log = LoggerFactory.getLogger(AsyncApplicationWithAnnotation.class);
/**
* 自定义异步线程池
* 如果没有这个方法,则使用默认的线程池
* @return
*/
@Bean
public AsyncTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("Anno-Executor");//设置线程名称的前缀
executor.setCorePoolSize(5);//设置核心线程数
executor.setMaxPoolSize(10);//设置最大线程数
// 设置拒绝策略
executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// .....
}
});
// 使用预定义的异常处理类
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
public static void main(String[] args) {
log.info("Start AsyncApplication.. ");
SpringApplication.run(AsyncApplicationWithAnnotation.class, args);
}
}
现在写测试类:
package com.hry.spring.async.annotation;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.hry.spring.async.annotation.AsyncApplicationWithAnnotation;
import com.hry.spring.async.annotation.AsyncDemo;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=AsyncApplicationWithAnnotation.class)
public class AsyncApplicationWithAnnotationTests {
@Autowired
private AsyncDemo asyncDemo;
@Test
public void contextLoads() throws InterruptedException, ExecutionException {
asyncDemo.asyncInvokeSimplest();
asyncDemo.asyncInvokeWithParameter("test");
Future<String> future = asyncDemo.asyncInvokeReturnFuture(1000);
System.out.println(future.get());
}
}
启动测试类,结果如下:

说明启动异步线程池成功,执行上面的3个方法分别用了3个线程。
再说一下XML配置文件配置的方式:
我们先创建XML配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
default-lazy-init="false">
<!-- 等价于 @EnableAsync, executor指定线程池 -->
<task:annotation-driven executor="xmlExecutor"/>
<!-- id指定线程池产生线程名称的前缀 -->
<task:executor
id="xmlExecutor"
pool-size="3-20"
queue-capacity="100"
keep-alive="120"
rejection-policy="CALLER_RUNS"/>
</beans>
其中id表示线程名称的前缀,pool-size表示线程池的大小,“3-20”表示线程池的最大线程数为20,最小线程数为3,也可以设置成一个值,如:pool-size=5,则表示线程池的核心线程数和最大线程数相同,都是5。queue-capacity表示排队队列的长度。
项目启动时读取xml配置文件,如下:
package com.hry.spring.async.xml;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
/**
* 通过XML启动异步
* @author hry
*
*/
@SpringBootApplication
@ImportResource("classpath:/async/spring_async.xml")
public class AsyncApplicationWithXML {
private static final Logger log = LoggerFactory.getLogger(AsyncApplicationWithXML.class);
public static void main(String[] args) {
log.info("Start AsyncApplication.. ");
SpringApplication.run(AsyncApplicationWithXML.class, args);
}
}
编写测试类:
package com.hry.spring.async.xml;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=AsyncApplicationWithXML.class)
public class AsyncApplicationWithXMLTest {
@Autowired
private AsyncDemo asyncDemo;
@Test
public void contextLoads() throws InterruptedException, ExecutionException {
asyncDemo.asyncInvokeSimplest();
asyncDemo.asyncInvokeWithParameter("test");
Future<String> future = asyncDemo.asyncInvokeReturnFuture(100);
System.out.println(future.get());
}
}
测试结果如下:

测试成功。
标签:handler sys def art cti 提高 unit 调用 线程
原文地址:https://www.cnblogs.com/gaopengfirst/p/10846179.html