登陆

章鱼彩票app官网下载-Spring运用ThreadPoolTaskExecutor自定义线程池及完成异步调用

admin 2019-12-14 280人围观 ,发现0个评论

每一个成功人士的背面,必定从前做出过英勇而又孤单的决议。

抛弃不难,但坚持很帅~

多线程一直是作业或面试过程中的高频知识点,今日给我们共享一下运用 ThreadPoolTaskExecutor 来自界说线程池和完成异步调用多线程。

一、ThreadPoolTaskExecutor

本文选用 Executors 的工厂办法进行装备。

1、将线程池用到的参数界说到装备文件中

在项目的 resources 目录下创立 executor.properties 文件,并增加如下装备:

# 异步线程装备
# 中心线程数
async.executor.thread.core_pool_size=5
# 最大线程数
async.executor.thread.max_pool_size=8
# 使命行列巨细
async.executor.thread.queue_capacity=2
# 线程池中线程的称号前缀
async.executor.thread.name.prefix=async-service-
# 缓冲行列中线程的闲暇时刻
async.executor.thread.keep_alive_seconds=100

2、Executors 的工厂装备

2.1、装备概况

@Configuration
// @PropertySource是找的target目录下classes目录下的文件,resources目录下的文件编译后会生成在classes目录
@PropertySource(value = {"classpath:executor.properties"}, ignoreResourceNotFound=false, encoding="UTF-8")
@Slf4j
public class ExecutorConfig {

@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Value("${async.executor.thread.keep_alive_seconds}")
private int keepAliveSeconds;

@Bean(name = "asyncTaskExecutor")
public ThreadPoolTaskExecutor taskExecutor {
log.info("发动");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor;
// 中心线程数
executor.setCorePoolSize(corePoolSize);
// 最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 使命行列章鱼彩票app官网下载-Spring运用ThreadPoolTaskExecutor自定义线程池及完成异步调用巨细
executor.setQueueCapacity(queueCapacity);
// 线程前缀名
executor.setThreadNamePrefix(namePrefix);
// 线程的闲暇时刻
executor.setKeepAliveSeconds(keepAliveSe章鱼彩票app官网下载-Spring运用ThreadPoolTaskExecutor自定义线程池及完成异步调用conds);
// 回绝战略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPoli章鱼彩票app官网下载-Spring运用ThreadPoolTaskExecutor自定义线程池及完成异步调用cy);
// 线程初始化
executor.initialize;
return executor;
}
}

2.2、注解阐明

  • @Configuration:Spring 容器在发动时,会加载带有 @Configuration 注解的类,对其间带有 @Bean 注解的办法进行处理。

  • @Bean:是一个办法等级上的注解,首要用在 @Configuration 注解的类里,也能够用在 @Component 注解的类里。增加的 bean 的 id 为办法名。

  • @PropertySource:加载指定的装备文件。value 值为要加载的装备文件,ignoreResourceNotFound 意思是假如加载的文件找不到,程序是否疏忽它。默以为 false 。假如为 true ,则代表加载的装备文件不存在,程序不报错。在实践项目开发中,最好设置为 false 。假如 application.properties 文件中的特点与自界说装备文件中的特点重复,则自界说装备文件中的特点值被掩盖,加载的是 application.properties 文件中的装备特点。

  • @Slf4j:lombok 的日志输出东西,加上此注解后,可直接调用 log 输出各个等级的日志。

  • @Value:调用装备文件中的特点并给特点赋予值。

2.3、线程池装备阐明

  • 中心线程数:线程池创立时分初始化的线程数。当线程数超越中心线程数,则超越的线程则进入使命行列。

  • 最大线程数:只要在使命行列满了之后才会请求超越中心线程数的线程。不能小于中心线程数。

  • 使命行列:线程数大于中心线程数的部分进入使命行列。假如使命行列足够大,超出中心线程数的线程不会被创立,它会等候中心线程履行完它们自己的使命后再履行使命行列的使命,而不会再额外地创立线程。举例:假如有20个使命要履行,中心线程数:10,最大线程数:20,使命行列巨细:2。则体系会创立18个线程。这18个线程有履行完使命的,再履行使命行列中的使命。

  • 线程的闲暇时刻:当 线程池中的线程数量 大于 中心线程数 时,假如某线程闲暇时刻超越 keepAliveTime ,线程将被停止。这样,线程池能够动态的调整池中的线程数。

  • 回绝战略:假如(总使命数 - 中心线程数 - 使命行列数)-(最大线程数 - 中心线程数)> 0 的话,则会呈现线程回绝。举例:( 12 - 5 - 2 ) - ( 8 - 5 ) > 0,会呈现线程回绝。线程回绝又分为 4 种战略,分别为:

    • CallerRunsPolicy:交由调用方线程运转,比方 main 线程。

    • AbortPolicy:直接抛出反常。

    • DiscardPolicy:直接丢掉。

    • DiscardOldestPolicy:丢掉行列中最老的使命。

2.4、线程池装备个人了解

  • 当一个使命被提交到线程池时,首要检查线程池的中心线程是否都在履行使命。假如没有,则挑选一条线程履行使命。

  • 假如都在履行使命,检查使命行列是否已满。假如不满,则将使命存储在使命行列中。中心线程履行完自己的使命后,会再处理使命行列中的使命。

  • 假如使命行列已满,检查线程池(最大线程数操控)是否已满。假如不满,则创立一条线程去履行使命。假如满了,就依照战略处理无法履行的使命。

二、异步调用线程

一般 ThreadPoolTaskExecutor 是和 @Async 一同运用。在一个办法上增加 @Async 注解,标明是异步调用办法函数。@Async 后边加上线程池的办法名或 bean 称号,标明异步线程会加载线程池的装备。

@Component
@Slf4j
public class ThreadTest {
/**
* 每10秒循环一次,一个线程共循环10次。
*/
@Async("asyncTaskExecutor")
public void ceshi3 {
for (int i = 0; i <= 10; i++) {
log.info("ceshi3: " + i);
try {
Thread.sleep(2000 * 5);
} catch (InterruptedException e) {
e.printStackTrace;
}
}
}
}

补白:必定要在发动类上增加 @EnableAsync 注解,这样 @Async 注解才会收效。

三、多线程运用场景

1、守时使命 @Scheduled

// 在发动类上增加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class SpringBootStudyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootStudyApplication.class, args);
}
}
// @Component 注解将守时使命类归入 spring bean 办理。
@Component
public class listennerTest3 {

@Autowired
private ThreadTest t;

// 每1分钟履行一次ceshi3办法
@Scheduled(cron = "0 0/1 * * * ?")
public void run {
t.ceshi3;
}
}

ceshi3 办法调用线程池装备,且异步履行。

@Component
@Slf4j
public class ThreadTest {
/**
* 每10秒循环一次,一个线程共循环10次。
*/
@Async("asyncTaskExecutor")
public void ceshi3 {
for (int i = 0; i <= 10; i++) {
log.info("ceshi3: " + i);
try {
Thread.sleep(2000 * 5);
} catch (InterruptedException e) {
e.printStackTrace;
}
}
}
}

2、程序一发动就异步履行多线程

经过承继 CommandLineRunner 类完成。

@Component
public class ListennerTe聚宝币st implements CommandLineRunner {

@Autowired
private ThreadTest t;

@Override
public void run(String... args) {
for (int i = 1; i <= 10; i++) {
t.ceshi;
}
}
}
@Component
@Slf4j
public class ThreadTest {

@Async("asyncTaskExecutor")
public void ceshi {
log.info("ceshi");
}
}

3、界说一个 http 接口

还能够经过接口的方式来异步调用多线程:

@RestController
@RequestMapping("thread")
public class ListennerTest2 {

@Autowired
pr章鱼彩票app官网下载-Spring运用ThreadPoolTaskExecutor自定义线程池及完成异步调用ivate ThreadTest t;

@GetMapping("ceshi2")
public void run {
for (int i = 1; i < 10; i++) {
t.ceshi2;
}
}
}
@Component
@Slf4j
public class ThreadTest {

@Async("asyncTaskExecutor")
public void ceshi2 {
for (int i = 0; i <= 3; i++) {
log.info("ceshi2");
}
}
}

4、测验类

@RunWith(SpringRunner.class)
@SpringBootTest
public class ThreadRunTest {

@Autowired
private ThreadTest t;

@Test
public void thread1 {
for (int i = 1; i <= 10; i++) {
t.ceshi4;
}
}
}
@Component
@Slf4j
public class ThreadTest {
@Async("asyncTaskExecutor")
public void ceshi4 {
log.info("ceshi4");
}
}

四、总结

以上首要介绍了 ThreadPoolTaskExecutor 线程池的装备、运用、相重视解的含义及效果,也简略介绍了运用 @Async 来异步调用线程,最后又列举了多线程的运用场景,并配上了代码示例。期望我们喜爱。

欢迎我们留言评论

  • 章鱼彩票app官网下载-易会满:证券基金职业文化建设要抓好查核鼓励等关键环节
  • 铜箔龙头公司上调产品价格 市场需求望逐渐回暖
  • 章鱼彩票app官网下载-恒大分红大礼包就要来了 2018年派息或高达187亿元
  • 请关注微信公众号
    微信二维码
    不容错过
    Powered By Z-BlogPHP