JAVA八股与代码实践----如何设计一个动态线程池?简单代码示例

借鉴javaguide中的《如何设计一个动态线程池?》

1、代码实践

获取线程池的参数使用的是@endpoint端点

1. 注解说明

  • @Endpoint:用于标记一个类为自定义 Actuator 端点。
  • id:端点的唯一标识符,用于访问端点时的 URL 路径。
    • 例如,id = "myendpoint" 时,默认路径为 /actuator/myendpoint

2. 方法注解

@Endpoint 提供了三种注解,分别对应不同类型的 HTTP 方法:

  1. @ReadOperation:映射到 HTTP GET 请求,主要用于获取数据。
  2. @WriteOperation:映射到 HTTP POST 请求,主要用于修改数据。
  3. @DeleteOperation:映射到 HTTP DELETE 请求,主要用于删除资源。

3.调用方法(示例)

GET 请求:获取线程池状态

curl -X GET http://localhost:8080/actuator/threadpool

POST 请求:更新线程池配置

curl -X POST http://localhost:8080/actuator/threadpool \
    -H "Content-Type: application/json" \
    -d '{"corePoolSize": 15, "maxPoolSize": 30}'
DELETE 请求:重置线程池配置

curl -X DELETE http://localhost:8080/actuator/threadpool

pom.xml加入依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.yml中加入

management:
  endpoints:
    web:
      exposure:
        include: "*"

依次创建以下文件并写入代码

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MonitorThreadPool extends ThreadPoolExecutor {

    public MonitorThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, new LinkedBlockingQueue<>(100));
    }

    public int getCorePoolSize() {
        return super.getCorePoolSize();
    }

    public int getMaximumPoolSize() {
        return super.getMaximumPoolSize();
    }

    public int getActiveCount() {
        return super.getActiveCount();
    }

    public long getCompletedTaskCount() {
        return super.getCompletedTaskCount();
    }

    public long getTaskCount() {
        return super.getTaskCount();
    }
}
@Component
@Endpoint(id = "threadpool")
public class ThreadPoolEndpoint {

    @Autowired
    private ThreadPoolManager threadPoolManager;

    @ReadOperation
    public Map<String, Object> threadPoolsMetric() {
        Map<String, Object> metricMap = new HashMap<>();
        Map<String, Map<String, Object>> threadPools = new HashMap<>();

        threadPoolManager.getThreadPoolExecutorMap().forEach((name, executor) -> {
            Map<String, Object> poolInfo = new HashMap<>();
            poolInfo.put("coreSize", executor.getCorePoolSize());
            poolInfo.put("maxSize", executor.getMaximumPoolSize());
            poolInfo.put("activeCount", executor.getActiveCount());
            poolInfo.put("taskCount", executor.getTaskCount());
            poolInfo.put("completedTaskCount", executor.getCompletedTaskCount());

            threadPools.put(name, poolInfo);
        });

        metricMap.put("threadPools", threadPools);
        return metricMap;
    }
}
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class ThreadPoolManager {

    private final Map<String, MonitorThreadPool> threadPoolExecutorMap = new HashMap<>();

    public ThreadPoolManager() {
        threadPoolExecutorMap.put("threadPool1", createMonitorThreadPool(10, 20, 60));
        threadPoolExecutorMap.put("threadPool2", createMonitorThreadPool(5, 15, 30));
    }

    private MonitorThreadPool createMonitorThreadPool(int corePoolSize, int maxPoolSize, long keepAliveTime) {
        return new MonitorThreadPool(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS);
    }

    public Map<String, MonitorThreadPool> getThreadPoolExecutorMap() {
        return threadPoolExecutorMap;
    }

    public MonitorThreadPool getThreadPoolExecutor(String name) {
        return threadPoolExecutorMap.get(name);
    }

    public void addThreadPool(String name, int corePoolSize, int maxPoolSize, long keepAliveTime) {
        if (threadPoolExecutorMap.containsKey(name)) {
            throw new IllegalArgumentException("ThreadPool with name " + name + " already exists.");
        }
        threadPoolExecutorMap.put(name, createMonitorThreadPool(corePoolSize, maxPoolSize, keepAliveTime));
    }

    public void removeThreadPool(String name) {
        MonitorThreadPool executor = threadPoolExecutorMap.remove(name);
        if (executor != null) {
            executor.shutdown();
        }
    }
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ThreadPoolApplication {

    public static void main(String[] args) {
        SpringApplication.run(ThreadPoolApplication.class, args);
    }
}

2、测试代码

在网页输入localhost:8080/actuator/threadpool

结果显示

这里只获得了动态线程池的参数,如果要可视化可以使用  dynamic-tp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值