概念
线程池,是一种线程的使用模式,它为了降低线程使用中频繁的创建和销毁所带来的资源消耗与代价。
通过创建一定数量的线程,让他们时刻准备就绪等待新任务的到达,而任务执行结束之后再重新回来继续待命。
这就是线程池最核心的设计思路,[复用线程,平摊线程的创建与销毁的开销代价。]
自定义线程池代码实现
yml增加配置
task:
pool:
core-pool-size: 8
max-pool-size: 50
keep-alive-seconds: 60
queue-capacity: 50
自定义线程池
package cn.zy.study.thread.threadAsyn;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.concurrent.ThreadPoolExecutor;
@Data
@Component
@ConfigurationProperties(prefix = "task.pool")
@EnableAsync
@Slf4j
public class TaskExecutePool implements AsyncConfigurer {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
@Override
@Bean("myTaskAsyncPool")
public ThreadPoolTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(keepAliveSeconds);
executor.setKeepAliveSeconds(queueCapacity);
executor.setThreadNamePrefix("MyExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
log.error("Exception message - {}", throwable.getMessage());
log.error("Method name - {}", method.getName());
log.error("Parameter values - {}", Arrays.toString(objects));
if (throwable instanceof Exception) {
Exception exception = (Exception) throwable;
log.error("exception:{}", exception.getMessage());
}
throwable.printStackTrace();
};
}
}
使用示例代码
package cn.zy.study.thread.threadAsyn;
import cn.hutool.core.date.StopWatch;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Service
public class UseThreadTest {
@Autowired
ThreadPoolTaskExecutor myTaskAsyncPool;
public void test1() {
StopWatch sw = new StopWatch();
sw.start();
List<Integer> list = Arrays.asList(1, 2, 3);
List<String> results = list.stream()
.map(key ->
CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
}
return "结果" + key;
}, myTaskAsyncPool))
.map(CompletableFuture::join).collect(Collectors.toList());
System.out.println(results);
sw.stop();
System.out.println("耗时:" + sw.getTotalTimeMillis());
}
public void test2() {
StopWatch sw = new StopWatch();
sw.start();
List<Integer> list = Arrays.asList(1, 2, 3);
CompletableFuture[] array = list.stream()
.map(key ->
CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
try {
Thread.sleep(10000L);
} catch (Exception e) {
}
return "结果" + key;
}, myTaskAsyncPool))
.toArray(CompletableFuture[]::new);
Set<String> collect = Arrays.stream(array)
.map(completableFuture -> {
String result;
try {
result = (String) completableFuture.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
return result;
}).collect(Collectors.toSet());
System.out.println(new Gson().toJson(collect));
CompletableFuture.allOf(array).join();
sw.stop();
System.out.println("耗时:" + sw.getTotalTimeMillis());
}
}