线程池具体配置建议请看 : http://t.csdn.cn/nWaGH
在applicationContext.xml里添加
<bean id="userService" class="com.ssm.service.impl.UserServiceImpl">
<property name="executor">
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadNamePrefix" value="user-"/>
<property name="corePoolSize" value="20"/>
<property name="maxPoolSize" value="20"/>
<property name="keepAliveSeconds" value="300"/>
<property name="queueCapacity" value="100"/>
</bean>
</property>
</bean>
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
private AsyncTaskExecutor executor;
public void setExecutor(AsyncTaskExecutor executor) {
this.executor = executor;
}
public void getUserList() {
//多线程
executor.execute(()->{
System.out.println("========");
});
}
}
在applicationContext.xml同目录下创建文件threadPool.xml文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<task:annotation-driven executor="threadPool" />
<bean id="threadPool"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1000" />
<property name="maxPoolSize" value="1000" />
<property name="queueCapacity" value="2000" />
<property name="keepAliveSeconds" value="300" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
property>
bean>
beans>
然后后在applicationContext.xml中引入threadPool.xml:
定义的异步方法不能与被调用的异步方法在同一个类中,否则无效
这里模拟取消订单后发短信,有两个发送短信的方法
@Service
public class TranTest2Service {
// 发送提醒短信 1
@Async("threadPool")
public void sendMessage1() throws InterruptedException {
System.out.println("发送短信方法---- 1 执行开始");
Thread.sleep(5000); // 模拟耗时
System.out.println("发送短信方法---- 1 执行结束");
}
// 发送提醒短信 2
@Async("threadPool")
public void sendMessage2() throws InterruptedException {
System.out.println("发送短信方法---- 2 执行开始");
Thread.sleep(2000); // 模拟耗时
System.out.println("发送短信方法---- 2 执行结束");
}
}
调用发短信的方法
@Autowired
private TranTest2Service tranTest2Service;
// 订单处理任务
@GetMapping(path = "/orderTask")
public void orderTask() throws InterruptedException {
tranTest2Service.sendMessage1(); // 发短信的方法 1
tranTest2Service.sendMessage2(); // 发短信的方法 2
}
使用@Async效果

不使用@Async效果

@Async("threadPool")
public Future<String> asyncMethodWithReturnType() {
System.out.println("Execute method asynchronously - "
+ Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
以上示例可以发现,返回的数据类型为Future类型,其为一个接口。具体的结果类型为AsyncResult, 这个是需要注意的地方。
调用返回结果的异步方法示例:
public void testAsyncAnnotationForMethodsWithReturnType()
throws InterruptedException, ExecutionException {
System.out.println("Invoking an asynchronous method. "
+ Thread.currentThread().getName());
Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();
//阻塞全部线程完成后,获取线程返回的内容
future.get()
}
在异步方法中,如果出现异常,对于调用者caller而言,是无法感知的。如果确实需要进行异常处理,则按照如下方法来进行处理:
<task:annotation-driven executor="exceptionHandlingTaskExecutor" />
<bean id="exceptionHandlingTaskExecutor" class=" com.ssm.service.impl.ExceptionHandlingAsyncTaskExecutor">
<constructor-arg ref="threadPool" />
bean>
public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor {
private AsyncTaskExecutor executor;
public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) {
this.executor = executor;
}
//用独立的线程来包装,@Async其本质就是如此
@Override
public void execute(Runnable task) {
executor.execute(createWrappedRunnable(task));
}
@Override
public void execute(Runnable task, long startTimeout) {
//用独立的线程来包装,@Async其本质就是如此
executor.execute(createWrappedRunnable(task), startTimeout);
}
@Override
public Future submit(Runnable task) {
//用独立的线程来包装,@Async其本质就是如此。
return executor.submit(createWrappedRunnable(task));
}
@Override
public Future submit(final Callable task) {
//用独立的线程来包装,@Async其本质就是如此。
return executor.submit(createCallable(task));
}
private Callable createCallable(final Callable task) {
return new Callable() {
@Override
public Object call() throws Exception {
try {
return task.call();
} catch (Exception ex) {
handle(ex);
throw ex;
}
}
};
}
private Runnable createWrappedRunnable(final Runnable task) {
return new Runnable() {
@Override
public void run() {
try {
task.run();
} catch (Exception ex) {
handle(ex);
}
}
};
}
private void handle(Exception ex) {
//具体的异常逻辑处理的地方
System.err.println("Error during @Async execution: " + ex);
}
}
