定義線程池
- 在Spring Boot主類中定義一個(gè)線程池奸腺,比如:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@EnableAsync
@Configuration
class TaskPoolConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("taskExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
return executor;
}
}
}
上面我們通過ThreadPoolTaskExecutor
創(chuàng)建了一個(gè)線程池,同時(shí)設(shè)置了如下參數(shù):
- 核心線程數(shù)10:線程池創(chuàng)建時(shí)初始化的線程數(shù)
- 最大線程數(shù)20:線程池最大的線程數(shù)梯投,只有在緩沖隊(duì)列滿了之后才會(huì)申請(qǐng)超過核心線程數(shù)的線程
- 緩沖隊(duì)列200:用來緩沖執(zhí)行任務(wù)的隊(duì)列
- 允許線程的空閑時(shí)間60秒:超過了核心線程數(shù)之外的線程桐臊,在空閑時(shí)間到達(dá)之后會(huì)被銷毀
- 線程池名的前綴:設(shè)置好了之后可以方便我們定位處理任務(wù)所在的線程池
- 線程池對(duì)拒絕任務(wù)的處理策略:此處采用了
CallerRunsPolicy
策略轴合,當(dāng)線程池沒有處理能力的時(shí)候虐秦,該策略會(huì)直接在execute
方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù)平酿;如果執(zhí)行程序已被關(guān)閉,則會(huì)丟棄該任務(wù) - 設(shè)置線程池關(guān)閉的時(shí)候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean
- 設(shè)置線程池中任務(wù)的等待時(shí)間羡疗,如果超過這個(gè)時(shí)候還沒有銷毀就強(qiáng)制銷毀染服,以確保應(yīng)用最后能夠被關(guān)閉,而不是阻塞住
使用線程池
- 只需要在
@Async
注解中指定線程池名即可
@Slf4j
@Component
public class Task {
public static Random random = new Random();
@Async("taskExecutor")
public void doTaskOne() throws Exception {
log.info("開始做任務(wù)一");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任務(wù)一叨恨,耗時(shí):" + (end - start) + "毫秒");
}
@Async("taskExecutor")
public void doTaskTwo() throws Exception {
log.info("開始做任務(wù)二");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任務(wù)二,耗時(shí):" + (end - start) + "毫秒");
}
@Async("taskExecutor")
public void doTaskThree() throws Exception {
log.info("開始做任務(wù)三");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任務(wù)三挖垛,耗時(shí):" + (end - start) + "毫秒");
}
}
- 測(cè)試
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private Task task;
@Test
public void test() throws Exception {
task.doTaskOne();
task.doTaskTwo();
task.doTaskThree();
Thread.currentThread().join();
}
}