첫 번째 단계는, 스레드 풀을 구성
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();
//核心线程数量
threadPoolTaskExecutor.setCorePoolSize(2);
//最大线程数量
threadPoolTaskExecutor.setMaxPoolSize(5);
//队列中最大任务数
threadPoolTaskExecutor.setQueueCapacity(2);
//线程名称前缀
threadPoolTaskExecutor.setThreadNamePrefix("ThreadPool-");
//当达到最大线程数时如何处理新任务
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//线程空闲后最大存活时间
threadPoolTaskExecutor.setKeepAliveSeconds(60);
//初始化线程池
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
다음으로, 서비스를 만들
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<Integer> future = poolTaskExecutor.submit(() -> {
Thread.sleep(5000);
System.out.println(simpleDateFormat.format(new Date())+" "+Thread.currentThread().getName() + " 执行 " + index);
countDownLatch.countDown();
return 1;
});
}
countDownLatch.await();
return sum;
}
}
3 단계 : 컨트롤러 만들기
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+" 秒";
}
}
4 단계 : 시작 클래스 만들기
package com.kyy.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 启动程序
* @Auther:zhouhongliang
* @Date:2019/7/30
* @Description:
*/
@SpringBootApplication
@EnableAsync
public class SpringBootDemo {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo.class,args);
}
}
요약 : 스레드 풀 구성 지침
1, 속성 필드 설명
corePoolSize를이 : 스레드 풀 스레드의 최소 수를 유지하기 위해
keepAliveSeconds : 허용 자유 시간
maxPoolSize는 : 스레드 풀 스레드의 최대 수를 유지하기 위해
queueCapacity : 버퍼 큐
rejectedExecutionHandler : 거부 작업의 치료 전략
2, (Runable) 메소드 실행 실행
이 시간에 풀에서 스레드의 수가 corePoolSize를보다 작은 경우 풀의 스레드가 유휴 상태 인 경우에도, 또한 작업이 추가 처리하기 위해 새 스레드를 생성합니다.
이 시간에이 풀 corePoolSize를 스레드의 수와 동일하지만,이 Workqueue 버퍼 큐가 가득하지 않은 경우, 작업은 버퍼 큐에 배치됩니다.
이 시간은 풀 corePoolSize를 스레드의 수보다 큰 경우,이 Workqueue 버퍼 큐가 가득하고, 풀의 스레드 수는 작업이 추가 처리하기 위해 새 스레드를 구축의 maxPoolSize보다 작습니다.
태스크 핸들러 정책을 지정하여 시간 풀 corePoolSize를 스레드의 수보다 클 경우,이 Workqueue 버퍼 큐가 가득하고 풀에서 스레드 수가 maxPoolSize 같다 후 처리. 즉 : 우선 처리 작업은 다음과 같습니다 핵심 스레드 corePoolSize를, 작업 대기열이 Workqueue, 최대 스레드 maximumPoolSize를, 세 가지가 가득 경우, 사용 핸들러 처리 작업을 거부했다.
풀의 스레드 수는 corePoolSize를보다 큰 경우 대기 시간이 스레드이 KeepAliveTime를 초과하는 경우, 스레드는 종료됩니다. 이러한 방법으로, 스레드 풀 동적 풀의 스레드 수를 조정할 수 있습니다.