自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們一起聊聊如何動態(tài)調(diào)試線程池?

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

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

如何動態(tài)調(diào)試線程池?

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

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

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

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

一、什么是 JMX

JMX(Java Management Extensions)是 Java 平臺的一部分,它提供了一種管理和監(jiān)控 Java 應(yīng)用程序的標(biāo)準(zhǔn)方法。JMX 允許你監(jiān)控和管理系統(tǒng)資源、應(yīng)用程序和服務(wù),以及獲取關(guān)于這些實體的運行時信息。

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

JMX 架構(gòu)如下圖:

圖片圖片

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

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

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

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

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

二、代碼實踐

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

首先我們先來自定義一個動態(tài)線程池:

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);
    }
}

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

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

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

最后,我們自定義類實現(xiàn) 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);
    }
}

這個類也沒啥神奇的地方,唯一要注意的是,在構(gòu)造器中,我們調(diào)用了 registerMBean 方法,這個方法用來將當(dāng)前對象注冊到 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();
            }
        }
    }
}

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

程序啟動之后,我們使用 jconsole 連接上當(dāng)前應(yīng)用程序,如下圖:

圖片圖片

在 MBeans 這個選項卡位置,我們可以看到剛剛配置的 MBean,右側(cè)的 value 則可以直接修改,修改之后,回到應(yīng)用程序控制臺,我們會發(fā)現(xiàn)線程相關(guān)數(shù)據(jù)已經(jīng)發(fā)生變化了。

圖片圖片

可以看到,控制臺信息已經(jīng)發(fā)生變化。

責(zé)任編輯:武曉燕 來源: 江南一點雨
相關(guān)推薦

2025-02-28 08:46:24

框架微服務(wù)架構(gòu)

2023-07-11 08:34:25

參數(shù)流程類型

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調(diào)度Java

2024-09-30 09:33:31

2024-11-27 16:07:45

2023-04-03 00:09:13

2024-09-09 00:00:00

編寫技術(shù)文檔

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-09-10 21:42:31

2023-06-30 08:18:51

敏捷開發(fā)模式

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-05-09 08:24:11

JNA鏈接庫代碼

2021-12-10 07:45:48

字節(jié)音頻視頻

2021-11-04 06:58:31

CSS性能設(shè)備
點贊
收藏

51CTO技術(shù)棧公眾號