成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們一起聊聊如何動態調試線程池?

開發 前端
面試官表示設置線程池核心線程數是一個非常具有挑戰性的事情,問有無辦法能夠動態的設置線程池核心數,并觀察其執行效果?這個問題的難點在于它涉及到的技術點不是特別常用,該小伙伴面試的技術團隊剛好是做運維工具的,做一些監控軟件,所以剛好就問到這里。

這是有小伙伴最近在面深信服的時候遇到的一個問題,感覺比較有意思,松哥和大伙來聊一聊。

如何動態調試線程池?

面試官表示設置線程池核心線程數是一個非常具有挑戰性的事情,問有無辦法能夠動態的設置線程池核心數,并觀察其執行效果?

這個問題的難點在于它涉及到的技術點不是特別常用,該小伙伴面試的技術團隊剛好是做運維工具的,做一些監控軟件,所以剛好就問到這里。

那么松哥和大家簡單聊一聊這個話題。

其實這里主要是涉及到 Java 里邊一個比較古老的工具,JMX。

一、什么是 JMX

JMX(Java Management Extensions)是 Java 平臺的一部分,它提供了一種管理和監控 Java 應用程序的標準方法。JMX 允許你監控和管理系統資源、應用程序和服務,以及獲取關于這些實體的運行時信息。

簡單來說,就是通過 JMX 可以動態查看對象的運行信息,并且可以動態修改對象屬性。

JMX 架構如下圖:

圖片圖片

分析這張圖我們可以發現,JMX 底層是由很多不同的 MBeans 組成的,MBeans 是 JMX 的核心,它們是實現了特定接口的 Java 對象,用于表示可以被監控和管理的資源。MBeans 可以分為四種不同的類型,分別是:

  • Standard MBeans
  • Dynamic MBeans
  • Open MBeans
  • Model MBeans

這些 MBeans 的作用就是獲取對象的信息,或者是修改對象信息,都是通過 MBeans 來完成的。

所有的 MBeans 都需要注冊到 MBeanServer 上,然后再通過一些外部工具如 JMX、Web 瀏覽器等等,就可以去獲取或者修改 MBeans 的信息了。

這里的 MBean Server 是一個代理,它提供了一個注冊、檢索和操作 MBeans 的 API。它是 JMX 架構中的核心組件,負責管理所有 MBeans 的生命周期。

二、代碼實踐

接下來松哥通過一個簡單的案例,來和大家演示一下如何通過 JMX + jconsole 工具實現動態修改線程池信息。

首先我們先來自定義一個動態線程池:

public class DynamicThreadPool {
    private ThreadPoolExecutor threadPoolExecutor;

    public DynamicThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public ThreadPoolExecutor getThreadPoolExecutor() {
        return threadPoolExecutor;
    }

    public void setCorePoolSize(int corePoolSize) {
        threadPoolExecutor.setCorePoolSize(corePoolSize);
    }

    public void setMaximumPoolSize(int maximumPoolSize) {
        threadPoolExecutor.setMaximumPoolSize(maximumPoolSize);
    }
}

這個動態線程池實際上就是把我們傳統的線程池對象 ThreadPoolExecutor 封裝了一下,并且提供了兩個方法 setCorePoolSize 和 setMaximumPoolSize,通過這兩個方法我們可以動態設置線程池的線程數。

接下來我們自定義一個 MBean 接口,這個接口中提供四個方法,分別用來獲取或者設置線程數的信息。

public interface DynamicThreadPoolMXBean {
    int getCorePoolSize();
    void setCorePoolSize(int corePoolSize);
    int getMaximumPoolSize();
    void setMaximumPoolSize(int maximumPoolSize);
}

最后,我們自定義類實現 DynamicThreadPoolMXBean 接口,并繼承 StandardMBean 類,如下:

public class DynamicThreadPoolMBean extends StandardMBean implements DynamicThreadPoolMXBean {

    private DynamicThreadPool dynamicThreadPool;

    public DynamicThreadPoolMBean(DynamicThreadPool dynamicThreadPool) throws Exception {
        super(DynamicThreadPoolMXBean.class);
        this.dynamicThreadPool = dynamicThreadPool;
        registerMBean();
    }

    private void registerMBean() {
        try {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            ObjectName name = new ObjectName("org.javaboy:type=DynamicThreadPool");
            mbs.registerMBean(this, name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int getCorePoolSize() {
        return dynamicThreadPool.getThreadPoolExecutor().getCorePoolSize();
    }

    @Override
    public void setCorePoolSize(int corePoolSize) {
        dynamicThreadPool.setCorePoolSize(corePoolSize);
    }

    @Override
    public int getMaximumPoolSize() {
        return dynamicThreadPool.getThreadPoolExecutor().getMaximumPoolSize();
    }

    @Override
    public void setMaximumPoolSize(int maximumPoolSize) {
        dynamicThreadPool.setMaximumPoolSize(maximumPoolSize);
    }
}

這個類也沒啥神奇的地方,唯一要注意的是,在構造器中,我們調用了 registerMBean 方法,這個方法用來將當前對象注冊到 MBeanServer 上。

最后,我們就可以啟動自己的這段代碼了:

public class Main {
    public static void main(String[] args) throws Exception {
        DynamicThreadPool dynamicThreadPool = new DynamicThreadPool(2, 4, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10));
        DynamicThreadPoolMBean mBean = new DynamicThreadPoolMBean(dynamicThreadPool);

        while (true) {
            System.out.println("CorePoolSize:" + dynamicThreadPool.getThreadPoolExecutor().getCorePoolSize());
            System.out.println("MaximumPoolSize:" + dynamicThreadPool.getThreadPoolExecutor().getMaximumPoolSize());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

為了看到線程池的線程數量,我這里使用了一個死循環不停的打印線程數量信息,這樣一會通過 jconsole 修改線程池信息的時候,我們就能看到修改的效果了。

程序啟動之后,我們使用 jconsole 連接上當前應用程序,如下圖:

圖片圖片

在 MBeans 這個選項卡位置,我們可以看到剛剛配置的 MBean,右側的 value 則可以直接修改,修改之后,回到應用程序控制臺,我們會發現線程相關數據已經發生變化了。

圖片圖片

可以看到,控制臺信息已經發生變化。

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2025-02-28 08:46:24

框架微服務架構

2023-07-11 08:34:25

參數流程類型

2025-01-09 10:57:54

2024-06-04 07:52:04

2025-01-07 09:07:36

接口屬性路徑

2023-10-31 09:04:21

CPU調度Java

2023-08-10 08:28:46

網絡編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發模式

2022-05-24 08:21:16

數據安全API

2023-09-10 21:42:31

2024-09-30 09:33:31

2024-11-27 16:07:45

2024-02-20 21:34:16

循環GolangGo

2021-08-27 07:06:10

IOJava抽象

2024-09-09 00:00:00

編寫技術文檔

2023-04-03 00:09:13

2023-05-09 08:24:11

JNA鏈接庫代碼

2021-12-10 07:45:48

字節音頻視頻

2023-03-26 23:47:32

Go內存模型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 丝袜美腿一区二区三区动态图 | 欧美一区二区三区久久精品视 | 午夜伊人 | 亚洲欧美日韩电影 | 亚洲一区二区在线播放 | 伊人网综合 | 精品日韩在线 | 在线看亚洲 | 黄色毛片黄色毛片 | 精品日韩一区 | 久久伊人操 | 草比av| 国产精品一区二区在线 | 欧美中文字幕一区二区三区亚洲 | 欧美精品一区二区三区在线播放 | 精品一区二区三区免费视频 | 影音先锋欧美资源 | 成人国产在线视频 | 欧美福利| 日韩手机在线看片 | 色综合一区二区 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 嫩草懂你的影院入口 | av网站在线播放 | 小早川怜子xxxxaⅴ在线 | 精品一区国产 | 91精品国产91综合久久蜜臀 | 国产乱一区二区三区视频 | 国产午夜亚洲精品不卡 | 成人精品一区二区三区四区 | 中文字幕免费在线 | 国产亚洲欧美在线视频 | 精品伊人久久 | 亚洲欧美成人在线 | 亚洲高清在线免费观看 | 色婷婷久久综合 | 久久小视频| 色综合99| 国产视频福利一区 | 91久久北条麻妃一区二区三区 | 日韩久久精品 |