溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

發(fā)布時(shí)間:2021-03-01 17:00:19 來(lái)源:億速云 閱讀:1175 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

總線程數(shù) = 排隊(duì)線程數(shù) + 活動(dòng)線程數(shù) + 執(zhí)行完成的線程數(shù)

下面給出一個(gè)線程池使用示例,及教你獲取線程池狀態(tài)

private static ExecutorService es = new ThreadPoolExecutor(50, 100, 0L, TimeUnit.MILLISECONDS,
 new LinkedBlockingQueue<Runnable>(100000));
public static void main(String[] args) throws Exception {
 for (int i = 0; i < 100000; i++) {
 es.execute(() -> {
 System.out.print(1);
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 });
 }

 ThreadPoolExecutor tpe = ((ThreadPoolExecutor) es);
 while (true) {
 System.out.println();
 int queueSize = tpe.getQueue().size();
 System.out.println("當(dāng)前排隊(duì)線程數(shù):" + queueSize);
 int activeCount = tpe.getActiveCount();
 System.out.println("當(dāng)前活動(dòng)線程數(shù):" + activeCount);
 long completedTaskCount = tpe.getCompletedTaskCount();
 System.out.println("執(zhí)行完成線程數(shù):" + completedTaskCount);
 long taskCount = tpe.getTaskCount();
 System.out.println("總線程數(shù):" + taskCount);
 Thread.sleep(3000);
 }
}

線程池提交了 100000 個(gè)任務(wù),但同時(shí)只有 50 個(gè)線程在執(zhí)行工作,我們每陋 3 秒來(lái)獲取當(dāng)前線程池的運(yùn)行狀態(tài)。

第一次程序輸出:

當(dāng)前排隊(duì)線程數(shù):99950

當(dāng)前活動(dòng)線程數(shù):50

執(zhí)行完成線程數(shù):0

總線程數(shù)(排隊(duì)線程數(shù) + 活動(dòng)線程數(shù) + 執(zhí)行完成線程數(shù)):100000

第二次程序輸出:

當(dāng)前排隊(duì)線程數(shù):99800

當(dāng)前活動(dòng)線程數(shù):50

執(zhí)行完成線程數(shù):150

總線程數(shù)(排隊(duì)線程數(shù) + 活動(dòng)線程數(shù) + 執(zhí)行完成線程數(shù)):100000

活動(dòng)線程數(shù)和總線程數(shù)是不變的,排隊(duì)中的線程數(shù)和執(zhí)行完成的線程數(shù)不斷在變化,

直到所有任務(wù)執(zhí)行完畢,最后輸出:

當(dāng)前排隊(duì)線程數(shù):0

當(dāng)前活動(dòng)線程數(shù):0

執(zhí)行完成線程數(shù):100000

總線程數(shù)(排隊(duì)線程數(shù) + 活動(dòng)線程數(shù) + 執(zhí)行完成線程數(shù)):100000

這樣,你了解了這些 API 的使用方法,你想監(jiān)控線程池的狀態(tài)就非常方便了。

補(bǔ)充:Java線程及Jvm監(jiān)控工具

Java線程狀態(tài)

線程的五種狀態(tài)

* 新建:new(時(shí)間很短)

* 運(yùn)行:runnable

* 等待:waitting(無(wú)限期等待),timed waitting(限期等待)

* 阻塞:blocked

* 結(jié)束:terminated(時(shí)間很短)

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

Jvm監(jiān)控工具

一、jstack

介紹:

jstack用于打印出給定的java進(jìn)程ID或core file或遠(yuǎn)程調(diào)試服務(wù)的Java堆棧信息。

如果是在64位機(jī)器上,需要指定選項(xiàng)"-J-d64",Windows的jstack使用方式只支持以下的這種方式:jstack [-l] pid

如果java程序崩潰生成core文件,jstack工具可以用來(lái)獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發(fā)生問(wèn)題。

另外,jstack工具還可以附屬到正在運(yùn)行的java程序中,看到當(dāng)時(shí)運(yùn)行的java程序的java stack和native stack的信息, 如果現(xiàn)在運(yùn)行的java程序呈現(xiàn)hung的狀態(tài),jstack是非常有用的。

使用:

1、查看運(yùn)行程序的進(jìn)程號(hào)

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

2、jstack dump當(dāng)前線程狀態(tài)

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

3、根據(jù)當(dāng)前抓取到的信息進(jìn)行進(jìn)一步的分析

二、jvisualvm

jdk自帶有個(gè)jvisualvm工具、該工具是用來(lái)監(jiān)控java運(yùn)行程序的cpu、內(nèi)存、線程等的使用情況。并且使用圖表的方式監(jiān)控java程序、還具有遠(yuǎn)程監(jiān)控能力。

前期準(zhǔn)備

1、上傳tomcat到虛擬機(jī),webapps下存在Prefteach包

2、監(jiān)控之前先對(duì)jvm加監(jiān)控參數(shù),在tomcat的bin目錄下,catalina.sh文件中,搜索JAVA_OPTS=,在if里面,添加:

-Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.1.101

以上添加的內(nèi)容,需要修改兩處

1-改port

2-改hostname為本機(jī)ip

3、啟動(dòng)tomcat并打開(kāi)輸出日志:./startup.sh ../logs/catalina.out

jvisualvm使用

1、windows鍵+R鍵 輸入jvisualvm回車(chē)

2、右鍵遠(yuǎn)程添加遠(yuǎn)程主機(jī)

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

3、在 主機(jī)ip 上右鍵添加jmv連接

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

4、輸入遠(yuǎn)程連接的端口號(hào)點(diǎn)擊確定

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

5、雙擊192.168.1.101:10086,打開(kāi)如下圖所示的界面

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

6、進(jìn)入jvisualvm時(shí)時(shí)查看程序運(yùn)行狀態(tài)

怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控

注釋:在測(cè)試環(huán)境中有可能沒(méi)有權(quán)限在服務(wù)器上添加需要遠(yuǎn)程連接的配置,這樣只能使用jstack

補(bǔ)充:java 如何獲得線程池中正在執(zhí)行的線程數(shù)

java中線程池的監(jiān)控可以檢測(cè)到正在執(zhí)行的線程數(shù)。

通過(guò)線程池提供的參數(shù)進(jìn)行監(jiān)控。線程池里有一些屬性在監(jiān)控線程池的時(shí)候可以使用

taskCount:線程池需要執(zhí)行的任務(wù)數(shù)量。

completedTaskCount:線程池在運(yùn)行過(guò)程中已完成的任務(wù)數(shù)量。小于或等于taskCount。

largestPoolSize:線程池曾經(jīng)創(chuàng)建過(guò)的最大線程數(shù)量。通過(guò)這個(gè)數(shù)據(jù)可以知道線程池是否滿過(guò)。如等于線程池的最大大小,則表示線程池曾經(jīng)滿了。

getPoolSize:線程池的線程數(shù)量。如果線程池不銷(xiāo)毀的話,池里的線程不會(huì)自動(dòng)銷(xiāo)毀,所以這個(gè)大小只增不+ getActiveCount:獲取活動(dòng)的線程數(shù)。

通過(guò)擴(kuò)展線程池進(jìn)行監(jiān)控。通過(guò)繼承線程池并重寫(xiě)線程池的beforeExecute,afterExecute和terminated方法,我們可以在任務(wù)執(zhí)行前,執(zhí)行后和線程池關(guān)閉前干一些事情。

如監(jiān)控任務(wù)的平均執(zhí)行時(shí)間,最大執(zhí)行時(shí)間和最小執(zhí)行時(shí)間等。這幾個(gè)方法在線程池里是空方法。

如:

protected void beforeExecute(Thread t, Runnable r) { }

關(guān)于怎么對(duì)Java 線程池的運(yùn)行狀態(tài)進(jìn)行監(jiān)控問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI