作者:京東零售 王江波
1. 線程運(yùn)行狀態(tài)
1.1 total
??
??
??
通過(guò)上圖我們可以發(fā)現(xiàn)timed_waiting的topN線程都是查詢國(guó)補(bǔ)資質(zhì)的。
1.3 waiting
??
??
通過(guò)上圖我們可以發(fā)現(xiàn)waiting的topN線程都是查詢國(guó)補(bǔ)活動(dòng)的。
1.4 線程分析
下面我們分析上述兩種狀態(tài):
1. WAITING 狀態(tài)
?定義:當(dāng)一個(gè)線程處于 WAITING 狀態(tài)時(shí),它在等待另一個(gè)線程的特定操作(如通知或中斷),并且不會(huì)繼續(xù)執(zhí)行。
?觸發(fā)條件:線程進(jìn)入 WAITING 狀態(tài)的常見(jiàn)情況包括:
調(diào)用 Object.wait() 方法:線程在等待某個(gè)對(duì)象的監(jiān)視器(鎖)被其他線程通知。
調(diào)用 Thread.join() 方法:等待另一個(gè)線程完成。
調(diào)用 LockSupport.park() 方法:線程被阻塞,直到它被其他線程喚醒。
?恢復(fù):線程在 WAITING 狀態(tài)下將一直保持此狀態(tài),直到其他線程調(diào)用 notify() 或 notifyAll()(對(duì)于 Object.wait()),或者被中斷。
2. TIMED_WAITING 狀態(tài)
?定義:當(dāng)一個(gè)線程處于 TIMED_WAITING 狀態(tài)時(shí),它在等待某個(gè)條件的發(fā)生,但它會(huì)在指定的時(shí)間后自動(dòng)返回。
?觸發(fā)條件:線程進(jìn)入 TIMED_WAITING 狀態(tài)的常見(jiàn)情況包括:
調(diào)用 Thread.sleep(milliseconds):線程休眠指定的毫秒數(shù)。
調(diào)用 Object.wait(milliseconds):線程在等待某個(gè)對(duì)象的監(jiān)視器(鎖),并且在指定的時(shí)間內(nèi)等待。
調(diào)用 Thread.join(milliseconds):等待另一個(gè)線程完成,但有時(shí)間限制。
調(diào)用 LockSupport.parkNanos() 或 LockSupport.parkUntil()。
?恢復(fù):線程在 TIMED_WAITING 狀態(tài)下會(huì)在指定的時(shí)間結(jié)束后自動(dòng)恢復(fù),或者在其他線程調(diào)用 notify() 或 notifyAll() 時(shí)恢復(fù)。
| 狀態(tài) | 描述 | 觸發(fā)條件 | 恢復(fù)方式 | |----------------|------------------------------------------|---------------------------------------------|--------------------------------------------| | **WAITING** | 線程等待另一個(gè)線程的特定操作,不會(huì)繼續(xù)執(zhí)行 | `Object.wait()`, `Thread.join()`, `LockSupport.park()` | 其他線程調(diào)用 `notify()`/`notifyAll()` 或被中斷 | | **TIMED_WAITING** | 線程等待某個(gè)條件的發(fā)生,但有時(shí)間限制 | `Thread.sleep(milliseconds)`, `Object.wait(milliseconds)`, `Thread.join(milliseconds)` | 超過(guò)指定時(shí)間后自動(dòng)恢復(fù),或其他線程調(diào)用 `notify()`/`notifyAll()` |
下面我們結(jié)合實(shí)際代碼情況分析:
??
上文中 queryActTp 為 getActivityInfo 執(zhí)行并發(fā)任務(wù),其中包含兩個(gè)子任務(wù)、 queryQualityTp 為 getQualityInfo 執(zhí)行并發(fā)任務(wù),其中五個(gè)子任務(wù)。同時(shí)將這倆任務(wù)放到queryActAndQualityTp中并行。
getActivityInfo所在的秒級(jí)監(jiān)控如下:
??
getQualityInfo所在的秒級(jí)監(jiān)控如下;
??
上文中同樣的調(diào)用方式,但是出現(xiàn)了兩種線程狀態(tài),理論上應(yīng)該都是TIMED_WAITING。針對(duì)queryActTp我們可以發(fā)現(xiàn)堆棧信息中也是LockSupport.park而不是LockSupport.parkNanos。具體原因有待進(jìn)一步分析。
上述代碼中還有一個(gè)問(wèn)題就是A線程池中又并行調(diào)用了B、C線程池,在大流量情況下,CPU頻繁切換也會(huì)造成一定的CPU壓力,我們改寫這塊邏輯用一個(gè)線程池實(shí)現(xiàn)活動(dòng)和資質(zhì)的并發(fā)查詢。鑒于改動(dòng)較大,本次先不動(dòng)。
2. 火焰圖分析
??
2.1 wait線程
??
2.2 鎖性能
??
2.3 CPU采樣
??
2.3.1 getFatherActivity分析
??
Q1:調(diào)用場(chǎng)景:循環(huán)中調(diào)用getFatherActivity
Q2:查看配置數(shù)據(jù),json格式化后50000字符,大對(duì)象的反序列化
Q3:使用new ArrayList() 創(chuàng)建新對(duì)象
Q4:分組后只用了對(duì)象中的第一個(gè)元素,這里用toMap更佳
優(yōu)化1:
??
我們可以發(fā)現(xiàn)上文在循環(huán)中還是會(huì)存在多次的stream調(diào)用,繼而將toMap邏輯提到循環(huán)外,如下:
??
其他方法確實(shí)占用CPU較高,這里先不處理。
下文再優(yōu)化一項(xiàng)獲取并發(fā)線程執(zhí)行結(jié)果的工具類:
??
1、 allOf異常后,取消所有線程的繼續(xù)執(zhí)行。這么做為了防止有些線程超時(shí)后仍在執(zhí)行,浪費(fèi)部分CPU資源,線上發(fā)現(xiàn)確實(shí)存在較多的超時(shí)情況。 2、 這里的異常日志較多,根據(jù)異常類型進(jìn)行區(qū)分,去掉沒(méi)用的堆棧日志。
并發(fā)線程中所有的等待統(tǒng)一都使用了上文的方法,前文中的queryActTp處于WAITING狀態(tài)可能也是執(zhí)行沒(méi)取消導(dǎo)致,修改部署后再觀察分析。同樣的調(diào)用方式 queryQualityTp 處于Timed_waiting狀態(tài)可能與一次父任務(wù)中子任務(wù)的執(zhí)行耗時(shí)有關(guān),見(jiàn)上文監(jiān)控,活動(dòng)和資質(zhì)相差較大,具體原因有待進(jìn)一步分析。
審核編輯 黃宇
-
cpu
+關(guān)注
關(guān)注
68文章
11080瀏覽量
217085
發(fā)布評(píng)論請(qǐng)先 登錄
單核CPU網(wǎng)關(guān)和雙核CPU網(wǎng)關(guān)有什么區(qū)別
熱重分析儀在高分子材料中的應(yīng)用

【「# ROS 2智能機(jī)器人開發(fā)實(shí)踐」閱讀體驗(yàn)】視覺(jué)實(shí)現(xiàn)的基礎(chǔ)算法的應(yīng)用
【「# ROS 2智能機(jī)器人開發(fā)實(shí)踐」閱讀體驗(yàn)】機(jī)器人入門的引路書
【「# ROS 2智能機(jī)器人開發(fā)實(shí)踐」閱讀體驗(yàn)】+ROS2應(yīng)用案例
【「# ROS 2智能機(jī)器人開發(fā)實(shí)踐」閱讀體驗(yàn)】+內(nèi)容初識(shí)
名單公布!【書籍評(píng)測(cè)活動(dòng)NO.58】ROS 2智能機(jī)器人開發(fā)實(shí)踐
DLPC的boot flash在上機(jī)貼片之前需要預(yù)先燒寫程序嗎?
設(shè)計(jì)基于機(jī)器視覺(jué)的高分辨率雙遠(yuǎn)心物鏡

CPU占用率過(guò)高的常見(jiàn)原因
服務(wù)器cpu占用率高怎么解決
CPU時(shí)鐘周期、機(jī)器周期和指令周期的關(guān)系
優(yōu)秀實(shí)踐:I3C共享總線上的I2C器件

【「時(shí)間序列與機(jī)器學(xué)習(xí)」閱讀體驗(yàn)】+ 簡(jiǎn)單建議
Imagination CPU 系列研討會(huì) | RISC-V 平臺(tái)的性能分析和調(diào)試

評(píng)論