关于如何实现线程池参数动态化
自定义线程池类
public class MyThreadPool{
/**
* 最大可用的CPU核数
*/
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
/**
* 核心线程数量大小,如果是CPU 密集型任务(N+1),如果是I/O 密集型任务(2N),N为CPU核心数
*/
private static final int corePoolSize = CPU_COUNT * 2;
/**
* 线程池最大容纳线程数
*/
private static final int maximumPoolSize = CPU_COUNT * 4;
enum SingletonEnum {
//单例
INSTANCE;
private ThreadPoolExecutor executorService;
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("thread-pool-%d")
.setDaemon(true).build();
private SingletonEnum() {
executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 10L,
TimeUnit.MILLISECONDS, new ResizableCapacityLinkedBlockingQueue<>(100), threadFactory,new MyRejectedExecutionHandler());
}
public ThreadPoolExecutor getInstance() {
return executorService;
}
}
public static ThreadPoolExecutor getInstance() {
return MyThreadPool.SingletonEnum.INSTANCE.getInstance();
}
}
自定义拒绝策略和自定义队列
//自定义拒绝策略
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
executor.toString());
}
}
//自定义队列
//复制一份LinkedBlockingQueue的代码块,命名为ResizableCapacityLinkedBlockingQueue,并将 private final int capacity;这行代码改成:
private volatile int capacity;
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
Controller层
public class MyCustomizedController {
ThreadPoolExecutor cachedThreadPool = MyThreadPool.getInstance();
@ApiOperation(value = "修改核心线程数", notes = "")
@GetMapping("/corePoolSize")
public ResponseVO setCorePoolSize(@RequestParam("corePoolSize") Integer corePoolSize) {
if(cachedThreadPool.getMaximumPoolSize()<corePoolSize){
return ResponseVO.success("设置失败,目标核心线程数大于前最大线程数,请同时设置两者的值或重新设置值");
}
cachedThreadPool.setCorePoolSize(corePoolSize);
return ResponseVO.success("设置成功");
}
@ApiOperation(value = "修改最大线程数", notes = "")
@GetMapping("/maximumPoolSize")
public ResponseVO setMaximumPoolSize(@RequestParam("maximumPoolSize") Integer maximumPoolSize) {
cachedThreadPool.setMaximumPoolSize(maximumPoolSize);
return ResponseVO.success("设置成功");
}
@ApiOperation(value = "修改核心线程数和最大线程数", notes = "")
@GetMapping("/coreAndMax")
public ResponseVO setcoreAndMax(@RequestParam("corePoolSize") Integer corePoolSize,@RequestParam("maximumPoolSize") Integer maximumPoolSize) {
if(corePoolSize>maximumPoolSize){
return ResponseVO.success("设置失败,核心线程数不应大于最大线程数");
}
cachedThreadPool.setCorePoolSize(corePoolSize);
cachedThreadPool.setMaximumPoolSize(maximumPoolSize);
return ResponseVO.success("设置成功");
}
@ApiOperation(value = "修改队列长度", notes = "")
@GetMapping("/capacity")
public ResponseVO setCapacity(@RequestParam("capacity") Integer capacity) {
ResizableCapacityLinkedBlockingQueue queue = (ResizableCapacityLinkedBlockingQueue) cachedThreadPool.getQueue();
queue.setCapacity(capacity);
return ResponseVO.success("设置成功");
}
@ApiOperation(value = "线程池情况",notes = "")
@GetMapping("/poolStatus")
public ResponseVO getPoolStatus(){
log.info("查看当前线程池状态");
String str = getStatus();
return ResponseVO.success("线程池情况:"+str);
}
private String getStatus() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ResizableCapacityLinkedBlockingQueue queue = (ResizableCapacityLinkedBlockingQueue) cachedThreadPool.getQueue();
String str =sdf.format(new Date())+Thread.currentThread().getName() + "-" +
"核心线程数:" + cachedThreadPool.getCorePoolSize() +
",活动线程数" + cachedThreadPool.getActiveCount() +
",最大线程数" + cachedThreadPool.getMaximumPoolSize() +
",线程池活跃度" + divide(cachedThreadPool.getActiveCount(), cachedThreadPool.getMaximumPoolSize()) +
",任务完成数" + cachedThreadPool.getCompletedTaskCount() +
",队列大小" + (queue.size() + queue.remainingCapacity()) +
",当前排队线程数" + queue.size() +
",队列剩余大小" + queue.remainingCapacity() +
",队列使用度" + divide(queue.size(), queue.size() + queue.remainingCapacity());
log.info(str);
return str;
}
/**
* 保留两位小数
* @param num1
* @param num2
* @return
*/
private static String divide(int num1, int num2) {
return String.format("%1.2f%%", Double.parseDouble(num1 + "") / Double.parseDouble(num2 + "") * 100);
}
}
配合CountDownLatch并发编程工具类使用
//n个任务
ThreadPoolExecutor cachedThreadPool = MyThreadPool.getInstance();
CountDownLatch countDownLatch = new CountDownLatch(n);
cachedThreadPool.execute(
()->{
//业务代码****
countDownLatch.countDown();
});
try {
countDownLatch.await();
} catch (Exception e) {
log.info("任务中断");
}