没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
2页
主要给大家介绍了关于Spring Boot利用@Async异步调用:ThreadPoolTaskScheduler线程池的优雅关闭的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
资源推荐
资源详情
资源评论
Spring Boot利用利用@Async异步调用:异步调用:ThreadPoolTaskScheduler线程池的优雅关闭线程池的优雅关闭
详解详解
主要给大家介绍了关于Spring Boot利用@Async异步调用:ThreadPoolTaskScheduler线程池的优雅关闭的相关资料,文中通过示例代码介绍的非常详
细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
前言前言
之前分享了一篇关于Spring Boot中使用@Async来实现异步任务和线程池控制的文章:《Spring Boot使用@Async实现异步调用:自定义线程池》。由于最近身边也发现了
不少异步任务没有正确处理而导致的不少问题,所以在本文就接前面内容,继续说说线程池的优雅关闭,主要针对ThreadPoolTaskScheduler线程池。
问题现象问题现象
在上篇文章的例子Chapter4-1-3中,我们定义了一个线程池,然后利用@Async注解写了3个任务,并指定了这些任务执行使用的线程池。在上文的单元测试中,我们没有具
体说说shutdown相关的问题,下面我们就来模拟一个问题现场出来。
第一步:如前文一样,我们定义一个ThreadPoolTaskScheduler线程池:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@EnableAsync
@Configuration
class TaskPoolConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
executor.setPoolSize(20);
executor.setThreadNamePrefix("taskExecutor-");
return executor;
}
}
}
第二步:改造之前的异步任务,让它依赖一个外部资源,比如:Redis
@Slf4j
@Component
public class Task {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Async("taskExecutor")
public void doTaskOne() throws Exception {
log.info("开始做任务一");
long start = System.currentTimeMillis();
log.info(stringRedisTemplate.randomKey());
long end = System.currentTimeMillis();
log.info("完成任务一,耗时:" + (end - start) + "毫秒");
}
@Async("taskExecutor")
public void doTaskTwo() throws Exception {
log.info("开始做任务二");
long start = System.currentTimeMillis();
log.info(stringRedisTemplate.randomKey());
long end = System.currentTimeMillis();
log.info("完成任务二,耗时:" + (end - start) + "毫秒");
}
@Async("taskExecutor")
public void doTaskThree() throws Exception {
log.info("开始做任务三");
long start = System.currentTimeMillis();
log.info(stringRedisTemplate.randomKey());
long end = System.currentTimeMillis();
log.info("完成任务三,耗时:" + (end - start) + "毫秒");
}
}
注意:注意:这里省略了pom.xml中引入依赖和配置redis的步骤
第三步:修改单元测试,模拟高并发情况下ShutDown的情况:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private Task task;
@Test
@SneakyThrows
public void test() {
for (int i = 0; i < 10000; i++) {
task.doTaskOne();
task.doTaskTwo();
task.doTaskThree();
if (i == 9999) {
System.exit(0);
}
}
}
}
说明:通过for循环往上面定义的线程池中提交任务,由于是异步执行,在执行过程中,利用System.exit(0)来关闭程序,此时由于有任务在执行,就可以观察这些异步任务的
销毁与Spring容器中其他资源的顺序是否安全。
第四步:运行上面的单元测试,我们将碰到下面的异常内容。
org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:204) ~[spring-data-redis-1.8.10.RELEASE.jar:na]
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:348) ~[spring-data-redis-1.8.10.RELEASE.jar:na]
资源评论
weixin_38642897
- 粉丝: 2
- 资源: 896
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功