印象中记得只要启用@async注解就可以,然而印象只是印象。。。。
spring异步可以实现什么?
可以开更多的线程,去分片执行,提高效率,遇到处理数据大的业务时,可以省去等待返回时间,在后台运行,
例如pc端发布活动优惠时需要推送给app所有用户,这时就可以使用spring异步
(1)需要Xml中要引用命名空间
在你的配置文件中添加如下
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation 中添加如下(看清楚版本)
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.2.xsd
(2) 进行开启
XML方式
<task:annotation-driven executor="asyncExecutor" />
<task:executor id="asyncExecutor" pool-size="10-200" queue-capacity="10" keep-alive="10" rejection-policy="CALLER_RUNS"/>
<task:executor 配置属性 /> | 描述 |
pool-size | core size:最小的线程数,缺省:1 max size:最大的线程数,缺省:Integer.MAX_VALUE |
queue-capacity | 当线程池中最小的线程数被占用满后,新的任务会被放进队列queue里面, 当这个queue的capacity也被占满之后, pool里面会创 建新线程处理这个任务,直到总线程数达到了最大线程数maxsize, 这时系统会拒绝这个任务并抛出TaskRejectedException异常(缺省配置的情况下, 可以通过rejection-policy来决定如何处理这种情况)。缺省值为:Integer.MAX_VALUE |
keep-alive | 超过coresize最小线程数的那些线程,任务完成后,再经过这个设置的时长(单位:秒)会被结束掉, 这样的话线程池可以动态的调整池中的线程数 |
rejection-policy | ABORT(缺省):抛出TaskRejectedException异常,然后不执行 DISCARD:不执行,也不抛出异常即放弃该线程 DISCARD_OLDEST:丢弃queue中最旧的那个任务 CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行(不再异步) |
以上转载自 >>>>>>>点击打开链接
java配置方式
package rent.basecore.utils;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@ComponentScan("rent.basecore.AsTest")//指定你的异步方法位置,如果你的异步方法在xml配置的扫描位置中,可以忽略注释调
@EnableAsync
public class SpringAsync implements AsyncConfigurer {
private int corePoolSize = 10;
private int maxPoolSize = 10;
private int queueCapacity = 5;
private String ThreadNamePrefix = "MyLogExecutor-";
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix(ThreadNamePrefix);
executor.setKeepAliveSeconds(1);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
System.out.println("============");
return null;
}
}
(3)写你的需要进行异步执行的方法
@Async
public void noticeNewsAndMessage(HlAppointmentAll hlAppointmentAll) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("===================="+i+"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"+Thread.currentThread().getName());
}
/*iSmsUtilService.batchSmsSend(phoneNos, employee_phone, date, project, housekeeper, order_house, sign);*/
}
注意:
1.需要public 修饰
2.不可以重复扫描异步方法所在包,重复扫描会不起作用(这里就要注意你的配置文件,别问我为什么,
我也不知道。。。。)
3.如果想要使用事务,别在异步方法上面添加事务注解,没用,可以在异步方法内调用的方法上添加事务
4.调用异步方法的方法和异步方法不可以在同一个类中
5.记得按照上面参数说明合理设置你的线程数(别忽略~~~~)
6.不管是哪种配置启用,都要记得在你的xml中引用命名空间
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
在找资料的过程中,真是纠结了,好多博客里面写的不清楚,大多写的是正常情况,没有注意点,例如使用注解async,或者就是什么省略开启过程。。。。真是够够的了
上面的java配置方式,在我测试过后,发现没多会就会线程中止,然后就自动重启了(毕竟算一种实现方法,有时间了好好研究下)。。。。在这说明下