第一步、配置線程池
萊蕪網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)建站自2013年起到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
package com.kyy.springboot.pool;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Auth: zhouhongliang
* Date:2019/8/1
*/
@Configuration
public class GlobalConfig {
@Bean
public ThreadPoolTaskExecutor defaultThreadPool(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//核心線程數(shù)量
threadPoolTaskExecutor.setCorePoolSize(2);
//最大線程數(shù)量
threadPoolTaskExecutor.setMaxPoolSize(5);
//隊(duì)列中最大任務(wù)數(shù)
threadPoolTaskExecutor.setQueueCapacity(2);
//線程名稱前綴
threadPoolTaskExecutor.setThreadNamePrefix("ThreadPool-");
//當(dāng)達(dá)到最大線程數(shù)時(shí)如何處理新任務(wù)
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//線程空閑后最大存活時(shí)間
threadPoolTaskExecutor.setKeepAliveSeconds(60);
//初始化線程池
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
第二步、創(chuàng)建Service
package com.kyy.springboot.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* Auth: zhouhongliang
* Date:2019/8/1
*/
@Service
public class BootService {
@Resource(name = "defaultThreadPool")
private ThreadPoolTaskExecutor poolTaskExecutor;
@Async
public void testPool() {
System.out.println("線程名稱:" + Thread.currentThread().getName());
}
public void testNoPool() {
System.out.println("線程名稱:" + Thread.currentThread().getName());
}
public int testPoolTaskExecutor(int n) throws InterruptedException, ExecutionException {
CountDownLatch countDownLatch = new CountDownLatch(n);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int sum = 0;
for (int i = 1; i <= n; i++) {
final int index = i;
final Future future = poolTaskExecutor.submit(() -> {
Thread.sleep(5000);
System.out.println(simpleDateFormat.format(new Date())+" "+Thread.currentThread().getName() + " 執(zhí)行 " + index);
countDownLatch.countDown();
return 1;
});
}
countDownLatch.await();
return sum;
}
}
第三步:創(chuàng)建Controller
package com.kyy.springboot.controller;
import com.kyy.springboot.service.BootService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutionException;
/**
* Auth: zhouhongliang
* Date:2019/8/1
*/
@RestController
public class PoolController {
@Autowired
private BootService bootService;
@RequestMapping("/pool")
public String pool(){
for (int i=0;i<100;i++){
bootService.testPool();
}
return "pool test";
}
@RequestMapping("/poolTask/{n}")
public String poolTask(@PathVariable int n){
long startTime = System.currentTimeMillis();
try {
bootService.testPoolTaskExecutor(n);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
return "poolTask test "+(endTime-startTime)/1000+" 秒";
}
}
第四步:創(chuàng)建啟動(dòng)類
package com.kyy.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 啟動(dòng)程序
* @Auther:zhouhongliang
* @Date:2019/7/30
* @Description:
*/
@SpringBootApplication
@EnableAsync
public class SpringBootDemo {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo.class,args);
}
}
總結(jié):線程池配置說明
1、屬性字段說明
corePoolSize:線程池維護(hù)線程的最少數(shù)量
keepAliveSeconds:允許的空閑時(shí)間
maxPoolSize:線程池維護(hù)線程的最大數(shù)量
queueCapacity:緩存隊(duì)列
rejectedExecutionHandler:對(duì)拒絕task的處理策略
2、 execute(Runable)方法執(zhí)行過程
如果此時(shí)線程池中的數(shù)量小于corePoolSize,即使線程池中的線程都處于空閑狀態(tài),也要?jiǎng)?chuàng)建新的線程來處理被添加的任務(wù)。
如果此時(shí)線程池中的數(shù)量等于 corePoolSize,但是緩沖隊(duì)列 workQueue未滿,那么任務(wù)被放入緩沖隊(duì)列。
如果此時(shí)線程池中的數(shù)量大于corePoolSize,緩沖隊(duì)列workQueue滿,并且線程池中的數(shù)量小于maxPoolSize,建新的線程來處理被添加的任務(wù)。
如果此時(shí)線程池中的數(shù)量大于corePoolSize,緩沖隊(duì)列workQueue滿,并且線程池中的數(shù)量等于maxPoolSize,那么通過handler所指定的策略來處理此任務(wù)。也就是:處理任務(wù)的優(yōu)先級(jí)為:核心線程corePoolSize、任務(wù)隊(duì)列workQueue、最大線程 maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務(wù)。
當(dāng)線程池中的線程數(shù)量大于corePoolSize時(shí),如果某線程空閑時(shí)間超過keepAliveTime,線程將被終止。這樣,線程池可以動(dòng)態(tài)的調(diào)整池中的線程數(shù)。