偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

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

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

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

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

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

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

一、什么是 JMX

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

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

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

圖片圖片

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

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

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

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

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

二、代碼實(shí)踐

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

首先我們先來自定義一個(gè)動(dòng)態(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);
    }
}

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

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

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

最后,我們自定義類實(shí)現(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è)類也沒啥神奇的地方,唯一要注意的是,在構(gòu)造器中,我們調(diào)用了 registerMBean 方法,這個(gè)方法用來將當(dāng)前對(duì)象注冊(cè)到 MBeanServer 上。

最后,我們就可以啟動(dòng)自己的這段代碼了:

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ù)量,我這里使用了一個(gè)死循環(huán)不停的打印線程數(shù)量信息,這樣一會(huì)通過 jconsole 修改線程池信息的時(shí)候,我們就能看到修改的效果了。

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

圖片圖片

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

圖片圖片

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

責(zé)任編輯:武曉燕 來源: 江南一點(diǎn)雨
相關(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

接口屬性路徑

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-04-03 00:09:13

2024-09-09 00:00:00

編寫技術(shù)文檔

2023-10-31 09:04:21

CPU調(diào)度Java

2023-06-30 08:18:51

敏捷開發(fā)模式

2023-09-10 21:42:31

2023-08-10 08:28:46

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

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

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

2024-11-27 16:07:45

2024-09-30 09:33:31

2023-05-09 08:24:11

JNA鏈接庫代碼

2022-08-30 13:48:16

LinuxMySQL內(nèi)存

2021-11-04 06:58:31

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

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