optimize thread statistics

This commit is contained in:
huoyo 2023-03-22 16:07:13 +08:00
parent 9fe09cc00d
commit fd249db452
8 changed files with 291 additions and 31 deletions

View File

@ -9,7 +9,7 @@
</div> </div>
<div align="center"> <div align="center">
<img src='https://shields.io/badge/version-2.3.7-green.svg'> <img src='https://shields.io/badge/version-2.3.9-green.svg'>
<img src='https://shields.io/badge/author-Chang Zhang-dbab09.svg'> <img src='https://shields.io/badge/author-Chang Zhang-dbab09.svg'>
<img src='https://shields.io/badge/dependencies-Spring|aspectjweaver|tomcat|UIKit|Metricflow-r.svg'> <img src='https://shields.io/badge/dependencies-Spring|aspectjweaver|tomcat|UIKit|Metricflow-r.svg'>
</div> </div>
@ -22,6 +22,7 @@
- ✅ Find exceptions occurred in methods - ✅ Find exceptions occurred in methods
- ✅ Email you after finding an overtime method - ✅ Email you after finding an overtime method
- ✅ Hot update online:you needn't restart it - ✅ Hot update online:you needn't restart it
- ✅ Thread manage:show threads information
- ✅ Easy to use:you needn't additional learning costs - ✅ Easy to use:you needn't additional learning costs
- ✅ Enough to add a pom dependency:you needn't additional deployment costs - ✅ Enough to add a pom dependency:you needn't additional deployment costs
@ -35,6 +36,7 @@
- ✅ 追踪系统异常,精确定位到方法 - ✅ 追踪系统异常,精确定位到方法
- ✅ 接口超时邮件通知,无需实时查看 - ✅ 接口超时邮件通知,无需实时查看
- ✅ 线上热更新:无需重启更新代码 - ✅ 线上热更新:无需重启更新代码
- ✅ 线程管理:线程实时统计与状态查看
- ✅ 使用简单,无技术学习成本 - ✅ 使用简单,无技术学习成本
- ✅ pom依赖即可无代码侵入无多余部署成本 - ✅ pom依赖即可无代码侵入无多余部署成本
@ -87,6 +89,13 @@ v2.2.5开始加入了邮件通知功能,当方法耗时超过阈值之后,
![输入图片说明](docs/v200/image.png) ![输入图片说明](docs/v200/image.png)
5.线程管理
v2.3.9开始加入了线程管理功能,可以统计线程状态和查看线程堆栈信息
![输入图片说明](docs/v220/xcgl.png)
![输入图片说明](docs/v220/xcgl2.png)
## 重要版本说明 ## 重要版本说明
> V1.0:基本功能 > V1.0:基本功能

BIN
docs/v220/xcgl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

BIN
docs/v220/xcgl2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -6,7 +6,7 @@
<groupId>cn.langpy</groupId> <groupId>cn.langpy</groupId>
<artifactId>ko-time</artifactId> <artifactId>ko-time</artifactId>
<version>2.3.8</version> <version>2.3.9</version>
<name>KoTime</name> <name>KoTime</name>
<description>A springboot tool for tracking the paths of the methods,which can help you find method's performances easily.</description> <description>A springboot tool for tracking the paths of the methods,which can help you find method's performances easily.</description>
<licenses> <licenses>

View File

@ -21,11 +21,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
/** /**
* zhangchang * zhangchang
@ -139,6 +137,7 @@ public class KoTimeController {
e.printStackTrace(); e.printStackTrace();
} }
} }
private String getResourceText(String fileName) { private String getResourceText(String fileName) {
ClassPathResource classPathResource = new ClassPathResource(fileName); ClassPathResource classPathResource = new ClassPathResource(fileName);
try (InputStream inputStream = classPathResource.getInputStream(); try (InputStream inputStream = classPathResource.getInputStream();
@ -257,6 +256,7 @@ public class KoTimeController {
} }
return true; return true;
} }
@PostMapping("/updateClass") @PostMapping("/updateClass")
@ResponseBody @ResponseBody
@Auth @Auth
@ -305,7 +305,6 @@ public class KoTimeController {
} }
private static File uploadFile(byte[] file, String fileName) throws IOException { private static File uploadFile(byte[] file, String fileName) throws IOException {
FileOutputStream out = null; FileOutputStream out = null;
try { try {
@ -342,6 +341,7 @@ public class KoTimeController {
HeapMemoryInfo heapMemoryInfo = usageService.getHeapMemoryInfo(); HeapMemoryInfo heapMemoryInfo = usageService.getHeapMemoryInfo();
return heapMemoryInfo; return heapMemoryInfo;
} }
@GetMapping("/getPhysicalMemoryInfo") @GetMapping("/getPhysicalMemoryInfo")
@ResponseBody @ResponseBody
@Auth @Auth
@ -363,9 +363,20 @@ public class KoTimeController {
@GetMapping("/getThreadsInfo") @GetMapping("/getThreadsInfo")
@ResponseBody @ResponseBody
@Auth @Auth
public List getThreadsInfo() { public Map getThreadsInfo(String state) {
ThreadUsageService usageService = ThreadUsageService.newInstance(); ThreadUsageService usageService = ThreadUsageService.newInstance();
List<ThreadInfo> threads = usageService.getThreads(); List<ThreadInfo> threads = usageService.getThreads();
return threads; threads = threads.stream().sorted(Comparator.comparing(ThreadInfo::getState)).collect(Collectors.toList());
Map<String, Long> stateCounting = threads.stream().collect(Collectors.groupingBy(ThreadInfo::getState, Collectors.counting()));
stateCounting.put("all",(long)threads.size());
Map map = new HashMap();
map.put("statistics", stateCounting);
if (StringUtils.hasText(state)) {
threads = threads.stream().filter(a -> a.getState().equals(state)).collect(Collectors.toList());
}
map.put("threads", threads);
return map;
} }
} }

View File

@ -37,4 +37,9 @@ public class ThreadUsageService {
} }
return list; return list;
} }
public List<ThreadInfo> getThreads(String state) {
List<ThreadInfo> threads = getThreads();
return threads.stream().filter(a -> a.getState().equals(state)).collect(Collectors.toList());
}
} }

View File

@ -505,9 +505,68 @@
loadCpuInfo(); loadCpuInfo();
loadHeapMemoryInfo(); loadHeapMemoryInfo();
loadPhysicalMemoryInfo(); loadPhysicalMemoryInfo();
loadThreadsInfo();
} }
}); });
} }
let threadMap = new Map();
function loadThreadsInfo(queryState) {
queryState = queryState || '';
$.get(concatToken('contextPath/koTime/getThreadsInfo?state='+queryState), function (data) {
let statistics = data['statistics'];
let all = statistics['all'];
let RUNNABLE = statistics['RUNNABLE'] || 0;
let BLOCKED = statistics['BLOCKED'] || 0;
let WAITING = statistics['WAITING'] || 0;
let TIMED_WAITING = statistics['TIMED_WAITING'] || 0;
document.querySelector("#threadNum").innerHTML = all;
document.querySelector("#runnableNum").innerHTML = RUNNABLE;
document.querySelector("#blockedNum").innerHTML = BLOCKED;
document.querySelector("#waitingNum").innerHTML = WAITING;
document.querySelector("#timedWaitingNum").innerHTML = TIMED_WAITING;
let element = document.getElementById('threadList');
let html = '';
let threads = data['threads'];
let colors = {
'RUNNABLE':'#32d296',
'BLOCKED':'#cc0c0c',
'WAITING':'#ad7070',
'TIMED_WAITING':'#ad7070'
}
for (let i = 0; i < threads.length; i++) {
let thread = threads[i];
let id = thread['id'];
let name = thread['name'];
let classType = thread['classType'];
let state = thread['state'];
let stacks = thread['stacks'];
threadMap[id+''] = stacks;
html+=`<li onclick="showThreadInfo('${id}')" style='color: #333;font-weight: 400;font-size: 14px;'>id=<span style="font-size: 16px;font-weight: 500;">${id}</span>&nbsp; &nbsp;name=${name}&nbsp; &nbsp;class=${classType}&nbsp; &nbsp;<span style='font-size: 10px;background-color: ${colors[state]};' class="uk-label uk-label-success">${state}</span></li>`;
}
element.innerHTML = html;
});
}
function showThreadInfo(id) {
let stacks = threadMap[id];
let html = '';
for (let i = 0; i < stacks.length; i++) {
let stack = stacks[i];
let className = stack['className']
let methodName = stack['methodName']
let fileName = stack['fileName']
let lineNumber = stack['lineNumber']
html+=`<li style='color: #333;font-weight: 400;font-size: 14px;'>${className}.${methodName}&nbsp; &nbsp;<span style='font-size: 10px;background-color: darkslategray;text-transform: unset' class="uk-label uk-label-success">${fileName}${lineNumber}</span></li>`;
}
let threadDetailDom = document.getElementById('thread-detail');
threadDetailDom.innerHTML = html;
UIkit.notification.closeAll();
UIkit.modal(document.getElementById("modal-thread")).show();
}
$(document).ready(function () { $(document).ready(function () {
refreshData(); refreshData();
}); });
@ -529,6 +588,7 @@
<li id="zl" class="uk-active"><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Summary</a></li> <li id="zl" class="uk-active"><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Summary</a></li>
<li id="jklb"><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Interfaces</a></li> <li id="jklb"><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Interfaces</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Exceptions</a></li> <li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Exceptions</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Threads</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Hot update</a></li> <li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Hot update</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Configurations</a></li> <li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Configurations</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Contact me</a><span title="Latest release" style="position: absolute;top:-10px;left: 90%;border-radius: 5px;text-transform: unset" class="uk-label" id="version-notice" onclick="window.location.href='http://www.kotime.cn/docs/kaiyuan#/v220/introduce'"></span></li> <li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Contact me</a><span title="Latest release" style="position: absolute;top:-10px;left: 90%;border-radius: 5px;text-transform: unset" class="uk-label" id="version-notice" onclick="window.location.href='http://www.kotime.cn/docs/kaiyuan#/v220/introduce'"></span></li>
@ -648,6 +708,50 @@
<li>exception 1 1&nbsp<span class="uk-label uk-label-danger">closed</span></li> <li>exception 1 1&nbsp<span class="uk-label uk-label-danger">closed</span></li>
</ul> </ul>
</li> </li>
<li style="margin-left: 30%;margin-right: 30%;">
<ul class="uk-flex-left" uk-tab>
<li class="uk-active"><a href="#" style="text-transform: capitalize">Number of thread</a></li>
</ul>
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
<div>
<div onclick="loadThreadsInfo('')" id="threadNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">ALL</span><br>
<span style="font-size: 30px;color: #020718;font-weight: bold" id="threadNum" >0</span>
</div>
</div>
<div>
<div onclick="loadThreadsInfo('RUNNABLE')" id="runnableNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">RUNNABLE</span>
<br>
<span style="font-size: 30px;color: #29da93;font-weight: bold" id="runnableNum">0</span>
</div>
</div>
<div>
<div onclick="loadThreadsInfo('BLOCKED')" id="blockedNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">BLOCKED</span>
<br>
<span style="font-size: 30px;color: #cc0c0c;font-weight: bold" id="blockedNum">0</span></div>
</div>
<div>
<div onclick="loadThreadsInfo('WAITING')" id="waitingNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">WAITING</span>
<br>
<span style="font-size: 30px;color: #ad7070;font-weight: bold" id="waitingNum">0</span></div>
</div>
<div>
<div onclick="loadThreadsInfo('TIMED_WAITING')" id="timedWaitingNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">TIMED_WAITING</span>
<br>
<span style="font-size: 30px;color: #ad7070;font-weight: bold" id="timedWaitingNum">0</span></div>
</div>
</div>
<ul class="uk-flex-left" uk-tab>
<li class="uk-active"><a href="#" style="text-transform: capitalize">Threads</a></li>
</ul>
<ul id="threadList" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 70%" class="uk-list uk-list-divider">
<li>thread 1 1&nbsp<span class="uk-label uk-label-success">0</span></li>
</ul>
</li>
<li style="margin-left: 35%;margin-right: 35%;"> <li style="margin-left: 35%;margin-right: 35%;">
<div class="uk-card uk-card-default uk-card-body"> <div class="uk-card uk-card-default uk-card-body">
<div id="classForm" > <div id="classForm" >
@ -709,7 +813,19 @@
<a href="http://www.kotime.cn/person?version=v2.3.7">Local plugin</a></div> <a href="http://www.kotime.cn/person?version=v2.3.7">Local plugin</a></div>
</li> </li>
</ul> </ul>
<div id="modal-thread" uk-modal>
<div class="uk-modal-dialog" style="width: 75%">
<button class="uk-modal-close-default" type="button" uk-close></button>
<div class="uk-modal-body uk-margin-auto-vertical" uk-overflow-auto>
<ul id="thread-detail" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 70%" class="uk-list uk-list-divider">
</ul>
</div>
<div class="uk-modal-footer uk-text-right">
<button class="uk-button uk-button-primary uk-modal-close" type="button">OK</button>
</div>
</div>
</div>
<div id="modal-exception" uk-modal> <div id="modal-exception" uk-modal>
<div class="uk-modal-dialog"> <div class="uk-modal-dialog">
<button class="uk-modal-close-default" type="button" uk-close></button> <button class="uk-modal-close-default" type="button" uk-close></button>

View File

@ -5,10 +5,10 @@
<style> <style>
UIKitCss UIKitCss
</style> </style>
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/css/uikit.min.css"/>--> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/css/uikit.min.css"/>
<!-- UIkit JS --> <!-- UIkit JS -->
<!-- <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit.min.js"></script>--> <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit.min.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit-icons.min.js"></script>--> <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit-icons.min.js"></script>
<script> <script>
UIKitJs; UIKitJs;
uiKitIconsJs; uiKitIconsJs;
@ -49,6 +49,7 @@
loadCpuInfo(); loadCpuInfo();
loadHeapMemoryInfo(); loadHeapMemoryInfo();
loadPhysicalMemoryInfo(); loadPhysicalMemoryInfo();
loadThreadsInfo();
} }
}); });
@ -430,7 +431,7 @@
function loadLatestVersion(){ function loadLatestVersion(){
$.ajax({ $.ajax({
url: 'http://www.kotime.cn/common/latestVersion?version=2.3.7', url: 'http://www.kotime.cn/common/latestVersion?version=2.3.8',
type: 'GET', type: 'GET',
cache: false, cache: false,
dataType: "json", dataType: "json",
@ -501,6 +502,65 @@
document.querySelector("#thisUsed").innerHTML = `${thisUsedValue.toFixed()}M`; document.querySelector("#thisUsed").innerHTML = `${thisUsedValue.toFixed()}M`;
}); });
} }
let threadMap = new Map();
function loadThreadsInfo(queryState) {
queryState = queryState || '';
$.get(concatToken('contextPath/koTime/getThreadsInfo?state='+queryState), function (data) {
let statistics = data['statistics'];
let all = statistics['all'];
let RUNNABLE = statistics['RUNNABLE'] || 0;
let BLOCKED = statistics['BLOCKED'] || 0;
let WAITING = statistics['WAITING'] || 0;
let TIMED_WAITING = statistics['TIMED_WAITING'] || 0;
document.querySelector("#threadNum").innerHTML = all;
document.querySelector("#runnableNum").innerHTML = RUNNABLE;
document.querySelector("#blockedNum").innerHTML = BLOCKED;
document.querySelector("#waitingNum").innerHTML = WAITING;
document.querySelector("#timedWaitingNum").innerHTML = TIMED_WAITING;
let element = document.getElementById('threadList');
let html = '';
let threads = data['threads'];
let colors = {
'RUNNABLE':'#32d296',
'BLOCKED':'#cc0c0c',
'WAITING':'#ad7070',
'TIMED_WAITING':'#ad7070'
}
for (let i = 0; i < threads.length; i++) {
let thread = threads[i];
let id = thread['id'];
let name = thread['name'];
let classType = thread['classType'];
let state = thread['state'];
let stacks = thread['stacks'];
threadMap[id+''] = stacks;
html+=`<li onclick="showThreadInfo('${id}')" style='color: #333;font-weight: 400;font-size: 14px;'>id=<span style="font-size: 16px;font-weight: 500;">${id}</span>&nbsp; &nbsp;name=${name}&nbsp; &nbsp;class=${classType}&nbsp; &nbsp;<span style='font-size: 10px;background-color: ${colors[state]};' class="uk-label uk-label-success">${state}</span></li>`;
}
element.innerHTML = html;
});
}
function showThreadInfo(id) {
let stacks = threadMap[id];
let html = '';
for (let i = 0; i < stacks.length; i++) {
let stack = stacks[i];
let className = stack['className']
let methodName = stack['methodName']
let fileName = stack['fileName']
let lineNumber = stack['lineNumber']
html+=`<li style='color: #333;font-weight: 400;font-size: 14px;'>${className}.${methodName}&nbsp; &nbsp;<span style='font-size: 10px;background-color: darkslategray;text-transform: unset' class="uk-label uk-label-success">${fileName}${lineNumber}</span></li>`;
}
let threadDetailDom = document.getElementById('thread-detail');
threadDetailDom.innerHTML = html;
UIkit.notification.closeAll();
UIkit.modal(document.getElementById("modal-thread")).show();
}
$(document).ready(function () { $(document).ready(function () {
refreshData(); refreshData();
}); });
@ -525,6 +585,7 @@
<li id="zl" class="uk-active"><a href="#" style="color: #edeef1;font-size: 14px">总览</a></li> <li id="zl" class="uk-active"><a href="#" style="color: #edeef1;font-size: 14px">总览</a></li>
<li id="jklb"><a href="#" style="color: #edeef1;font-size: 14px">接口列表</a></li> <li id="jklb"><a href="#" style="color: #edeef1;font-size: 14px">接口列表</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px">异常列表</a></li> <li><a href="#" style="color: #edeef1;font-size: 14px">异常列表</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px">线程列表</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px">热更新</a></li> <li><a href="#" style="color: #edeef1;font-size: 14px">热更新</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px">配置</a></li> <li><a href="#" style="color: #edeef1;font-size: 14px">配置</a></li>
<li><a href="#" style="color: #edeef1;font-size: 14px">技术支持</a><span title="点击查看版本发布信息" style="position: absolute;top:-10px;left: 90%;border-radius: 5px;text-transform: unset" class="uk-label" id="version-notice" onclick="window.location.href='http://www.kotime.cn/docs/kaiyuan#/v220/introduce'"></span></li> <li><a href="#" style="color: #edeef1;font-size: 14px">技术支持</a><span title="点击查看版本发布信息" style="position: absolute;top:-10px;left: 90%;border-radius: 5px;text-transform: unset" class="uk-label" id="version-notice" onclick="window.location.href='http://www.kotime.cn/docs/kaiyuan#/v220/introduce'"></span></li>
@ -640,6 +701,50 @@
<li>exception 1 1&nbsp<span class="uk-label uk-label-danger">未开启</span></li> <li>exception 1 1&nbsp<span class="uk-label uk-label-danger">未开启</span></li>
</ul> </ul>
</li> </li>
<li style="margin-left: 30%;margin-right: 30%;">
<ul class="uk-flex-left" uk-tab>
<li class="uk-active"><a href="#" >线程统计</a></li>
</ul>
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
<div>
<div onclick="loadThreadsInfo('')" id="threadNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">ALL</span><br>
<span style="font-size: 30px;color: #020718;font-weight: bold" id="threadNum" >0</span>
</div>
</div>
<div>
<div onclick="loadThreadsInfo('RUNNABLE')" id="runnableNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">RUNNABLE</span>
<br>
<span style="font-size: 30px;color: #29da93;font-weight: bold" id="runnableNum">0</span>
</div>
</div>
<div>
<div onclick="loadThreadsInfo('BLOCKED')" id="blockedNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">BLOCKED</span>
<br>
<span style="font-size: 30px;color: #cc0c0c;font-weight: bold" id="blockedNum">0</span></div>
</div>
<div>
<div onclick="loadThreadsInfo('WAITING')" id="waitingNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">WAITING</span>
<br>
<span style="font-size: 30px;color: #ad7070;font-weight: bold" id="waitingNum">0</span></div>
</div>
<div>
<div onclick="loadThreadsInfo('TIMED_WAITING')" id="timedWaitingNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
<span style="font-size: 10px;color: #3b3f4f">TIMED_WAITING</span>
<br>
<span style="font-size: 30px;color: #ad7070;font-weight: bold" id="timedWaitingNum">0</span></div>
</div>
</div>
<ul class="uk-flex-left" uk-tab>
<li class="uk-active"><a href="#" >线程列表</a></li>
</ul>
<ul id="threadList" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 70%" class="uk-list uk-list-divider">
<li>thread 1 1&nbsp<span class="uk-label uk-label-success">0</span></li>
</ul>
</li>
<li style="margin-left: 35%;margin-right: 35%;"> <li style="margin-left: 35%;margin-right: 35%;">
<div class="uk-card uk-card-default uk-card-body" style="border-radius: 5px"> <div class="uk-card uk-card-default uk-card-body" style="border-radius: 5px">
<div id="classForm" > <div id="classForm" >
@ -702,6 +807,20 @@
</li> </li>
</ul> </ul>
<div id="modal-thread" uk-modal>
<div class="uk-modal-dialog" style="width: 75%">
<button class="uk-modal-close-default" type="button" uk-close></button>
<div class="uk-modal-body uk-margin-auto-vertical" uk-overflow-auto>
<ul id="thread-detail" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 70%" class="uk-list uk-list-divider">
</ul>
</div>
<div class="uk-modal-footer uk-text-right">
<button class="uk-button uk-button-primary uk-modal-close" type="button">朕知道了</button>
</div>
</div>
</div>
<div id="modal-exception" uk-modal> <div id="modal-exception" uk-modal>
<div class="uk-modal-dialog"> <div class="uk-modal-dialog">
<button class="uk-modal-close-default" type="button" uk-close></button> <button class="uk-modal-close-default" type="button" uk-close></button>