内容简介:本文主要研究一下elasticsearch的DeadlockAnalyzerelasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/jvm/DeadlockAnalyzer.javaelasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/jvm/DeadlockAnalyzer.java
序
本文主要研究一下elasticsearch的DeadlockAnalyzer
DeadlockAnalyzer
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/jvm/DeadlockAnalyzer.java
public class DeadlockAnalyzer {
private static final Deadlock NULL_RESULT[] = new Deadlock[0];
private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
private static DeadlockAnalyzer INSTANCE = new DeadlockAnalyzer();
public static DeadlockAnalyzer deadlockAnalyzer() {
return INSTANCE;
}
private DeadlockAnalyzer() {
}
public Deadlock[] findDeadlocks() {
long deadlockedThreads[] = threadBean.findMonitorDeadlockedThreads();
if (deadlockedThreads == null || deadlockedThreads.length == 0) {
return NULL_RESULT;
}
Map<Long, ThreadInfo> threadInfoMap = createThreadInfoMap(deadlockedThreads);
Set<LinkedHashSet<ThreadInfo>> cycles = calculateCycles(threadInfoMap);
Set<LinkedHashSet<ThreadInfo>> chains = calculateCycleDeadlockChains(threadInfoMap, cycles);
cycles.addAll(chains);
return createDeadlockDescriptions(cycles);
}
private Deadlock[] createDeadlockDescriptions(Set<LinkedHashSet<ThreadInfo>> cycles) {
Deadlock result[] = new Deadlock[cycles.size()];
int count = 0;
for (LinkedHashSet<ThreadInfo> cycle : cycles) {
ThreadInfo asArray[] = cycle.toArray(new ThreadInfo[cycle.size()]);
Deadlock d = new Deadlock(asArray);
result[count++] = d;
}
return result;
}
private Set<LinkedHashSet<ThreadInfo>> calculateCycles(Map<Long, ThreadInfo> threadInfoMap) {
Set<LinkedHashSet<ThreadInfo>> cycles = new HashSet<>();
for (Map.Entry<Long, ThreadInfo> entry : threadInfoMap.entrySet()) {
LinkedHashSet<ThreadInfo> cycle = new LinkedHashSet<>();
for (ThreadInfo t = entry.getValue(); !cycle.contains(t); t = threadInfoMap.get(Long.valueOf(t.getLockOwnerId()))) {
cycle.add(t);
}
if (!cycles.contains(cycle)) {
cycles.add(cycle);
}
}
return cycles;
}
private Set<LinkedHashSet<ThreadInfo>> calculateCycleDeadlockChains(Map<Long, ThreadInfo> threadInfoMap,
Set<LinkedHashSet<ThreadInfo>> cycles) {
ThreadInfo allThreads[] = threadBean.getThreadInfo(threadBean.getAllThreadIds());
Set<LinkedHashSet<ThreadInfo>> deadlockChain = new HashSet<>();
Set<Long> knownDeadlockedThreads = threadInfoMap.keySet();
for (ThreadInfo threadInfo : allThreads) {
Thread.State state = threadInfo.getThreadState();
if (state == Thread.State.BLOCKED && !knownDeadlockedThreads.contains(threadInfo.getThreadId())) {
for (LinkedHashSet<ThreadInfo> cycle : cycles) {
if (cycle.contains(threadInfoMap.get(Long.valueOf(threadInfo.getLockOwnerId())))) {
LinkedHashSet<ThreadInfo> chain = new LinkedHashSet<>();
ThreadInfo node = threadInfo;
while (!chain.contains(node)) {
chain.add(node);
node = threadInfoMap.get(Long.valueOf(node.getLockOwnerId()));
}
deadlockChain.add(chain);
}
}
}
}
return deadlockChain;
}
private Map<Long, ThreadInfo> createThreadInfoMap(long threadIds[]) {
ThreadInfo threadInfos[] = threadBean.getThreadInfo(threadIds);
Map<Long, ThreadInfo> threadInfoMap = new HashMap<>();
for (ThreadInfo threadInfo : threadInfos) {
threadInfoMap.put(threadInfo.getThreadId(), threadInfo);
}
return unmodifiableMap(threadInfoMap);
}
//......
}
- DeadlockAnalyzer提供了findDeadlocks方法用于返回死锁线程的信息,该方法通过ThreadMXBean的findMonitorDeadlockedThreads方法获取deadlockedThreads数组,如果该数组为null或空,则返回NULL_RESULT,否则往下计算
- createThreadInfoMap方法根据threadIds从ThreadMXBean获取对应的threadInfo信息,然后组装成threadId与threadInfo的map;calculateCycles方法则是遍历该map,然后根据threadInfo的getLockOwnerId()构建cycles
- calculateCycleDeadlockChains方法则根据threadInfoMap及cycles构建cycleDeadlockChains,添加到cycles中,最后通过createDeadlockDescriptions方法构建Deadlock数组
Deadlock
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/jvm/DeadlockAnalyzer.java
public static class Deadlock {
private final ThreadInfo members[];
private final String description;
private final Set<Long> memberIds;
public Deadlock(ThreadInfo[] members) {
this.members = members;
Set<Long> builder = new HashSet<>();
StringBuilder sb = new StringBuilder();
for (int x = 0; x < members.length; x++) {
ThreadInfo ti = members[x];
sb.append(ti.getThreadName());
sb.append(" > ");
if (x == members.length - 1) {
sb.append(ti.getLockOwnerName());
}
builder.add(ti.getThreadId());
}
this.description = sb.toString();
this.memberIds = unmodifiableSet(builder);
}
public ThreadInfo[] members() {
return members;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Deadlock deadlock = (Deadlock) o;
if (memberIds != null ? !memberIds.equals(deadlock.memberIds) : deadlock.memberIds != null) return false;
return true;
}
@Override
public int hashCode() {
int result = members != null ? Arrays.hashCode(members) : 0;
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (memberIds != null ? memberIds.hashCode() : 0);
return result;
}
@Override
public String toString() {
return description;
}
}
- Deadlock包含了members、description、memberIds三个属性,其构造器会根据members来构建description
小结
- DeadlockAnalyzer提供了findDeadlocks方法用于返回死锁线程的信息,该方法通过ThreadMXBean的findMonitorDeadlockedThreads方法获取deadlockedThreads数组,如果该数组为null或空,则返回NULL_RESULT,否则往下计算
- createThreadInfoMap方法根据threadIds从ThreadMXBean获取对应的threadInfo信息,然后组装成threadId与threadInfo的map;calculateCycles方法则是遍历该map,然后根据threadInfo的getLockOwnerId()构建cycles
- calculateCycleDeadlockChains方法则根据threadInfoMap及cycles构建cycleDeadlockChains,添加到cycles中,最后通过createDeadlockDescriptions方法构建Deadlock数组
doc
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ajax Design Patterns
Michael Mahemoff / O'Reilly Media / 2006-06-29 / USD 44.99
Ajax, or Asynchronous JavaScript and XML, exploded onto the scene in the spring of 2005 and remains the hottest story among web developers. With its rich combination of technologies, Ajax provides a s......一起来看看 《Ajax Design Patterns》 这本书的介绍吧!