1. 程式人生 > 其它 >Java VisualVM 觀察自定義執行緒池

Java VisualVM 觀察自定義執行緒池

背景

在一次使用自定義執行緒池中,我發現了部分程式碼是用完沒有進行shutdown的,這樣是否會造成資源浪費?

一、首先我們把執行時時的執行緒數量打印出來,放上程式碼:然後開啟Java VisualVM進行觀測:




public class ThreadTest {

    public static void main(String[] args) throws Exception {

        AtomicInteger atomicInteger = new AtomicInteger();
        for (int i = 0; i < 10; i++) {
            test(atomicInteger);
        }
    }

    
public static void test(AtomicInteger atomicInteger) throws InterruptedException { //用於獲取到本java程序,進而獲取匯流排程數 RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); String jvmName = runtimeBean.getName(); System.out.println("JVM Name = " + jvmName); long
pid = Long.valueOf(jvmName.split("@")[0]); System.out.println("JVM PID = " + pid); ThreadMXBean bean = ManagementFactory.getThreadMXBean(); int n = 3000000; for (int i = 0; i < n; i++) { ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 1000, TimeUnit.SECONDS, new
LinkedBlockingDeque<>()); for (int j = 0; j < 10; j++) { executor.execute(() -> { System.out.println(atomicInteger.getAndIncrement()+"==="+ Thread.currentThread().getName()+"==當前執行緒總數為:" + bean.getThreadCount()); }); }
        // 此處控制是否釋放執行完執行緒
executor.shutdown(); } Thread.sleep(10000); System.out.println("執行緒總數為 = " + bean.getThreadCount()); } }

我們測試看看實際情況:

可以看到執行緒池有時候還沒來得及釋放的時候, 峰值是400多

非峰值很穩定在20多附近。

附上記憶體圖等情況:

第二次,因為如果不做執行緒睡眠,直接把服務幹掛了,連著visualVm都啟動不了, 我們程式碼需要調整下:

public class ThreadTest {

    public static void main(String[] args) throws Exception {

        AtomicInteger atomicInteger = new AtomicInteger();
        for (int i = 0; i < 10; i++) {
            test(atomicInteger);
        }
    }

    public static void  test(AtomicInteger atomicInteger) throws InterruptedException {
        //用於獲取到本java程序,進而獲取匯流排程數
        RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
        String jvmName = runtimeBean.getName();
        System.out.println("JVM Name = " + jvmName);
        long pid = Long.valueOf(jvmName.split("@")[0]);
        System.out.println("JVM PID  = " + pid);
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        int n = 3000000;
        for (int i = 0; i < n; i++) {
            ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 1000, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
            for (int j = 0; j < 10; j++) {
          // 此處執行緒睡眠 Thread.sleep(
500); executor.execute(() -> { System.out.println(atomicInteger.getAndIncrement()+"==="+ Thread.currentThread().getName()+"==當前執行緒總數為:" + bean.getThreadCount()); }); } // 此處控制執行緒執行完是否釋放 // executor.shutdown(); } Thread.sleep(10000); System.out.println("執行緒總數為 = " + bean.getThreadCount()); } }

調整後效果如下: 你發現執行緒數量永遠是網上升的

回收不了,已經越來越多了。

附上記憶體情況

三、結論

用完自定義執行緒池,一定要手動關閉shutDown掉池子