📄 threadutility.java
字号:
/*------------------------------------------------------------------------------Name: ThreadUtility.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE file------------------------------------------------------------------------------*/package org.xmlBlaster.util;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.io.Reader;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.StringTokenizer;import java.util.TreeMap;/** * Reads and compares two files containing stack traces. Output are only such stack traces which did not change (which are * the same in both) * * ThreadUtility * @author <a href="mailto:michele@laghi.eu">Michele Laghi</a> */public class ThreadUtility { // step one: read all threads private String name; private boolean daemon; private int prio; private String threadId; private String nId; private String lwpId; private String tail; private String head; private String[] stack; public ThreadUtility() { } private final static String getNextToken(StringTokenizer tokenizer) { String txt = tokenizer.nextToken(); if (txt.indexOf("\"") == 0 && txt.charAt(txt.length()-1) != '"') { StringBuffer buf = new StringBuffer(); buf.append(txt).append(" "); String tmp = null; while (tokenizer.hasMoreTokens()) { tmp = tokenizer.nextToken(); buf.append(tmp); if (tmp.charAt(tmp.length()-1) == '"') break; else buf.append(" "); } txt = buf.toString(); } return afterEquality(txt); } private final static String getTail(StringTokenizer tokenizer) { StringBuffer buf = new StringBuffer(); boolean isFirst = true; while (tokenizer.hasMoreTokens()) { if (!isFirst) buf.append(" "); else isFirst = false; buf.append(tokenizer.nextToken()); } return buf.toString(); } private final static String afterEquality(String txt) { int pos = txt.indexOf("="); if (pos < 0) return txt; return txt.substring(pos+1); } public final static boolean isHead(String line) { if (line == null || line.length() < 1) return false; return line.indexOf("tid=") > -1; } /** * Returns key/values where the key is the threadId and the value is the ThreadUtility object. Never returns null. * @param reader * @return */ public static Map getThreads(Reader reader) throws IOException { Map map = new TreeMap(); BufferedReader br = new BufferedReader(reader); String line = null; ThreadUtility thread = null; List stack = new ArrayList(); while ( (line=br.readLine()) != null) { if (isHead(line)) { if (thread != null) { thread.setStack((String[])stack.toArray(new String[stack.size()])); map.put(thread.getThreadId(), thread); } thread = new ThreadUtility(); thread.setHead(line); stack.clear(); } else { if (line.length() > 0) stack.add(line); } } return map; } public static String dumpUnchangedThreads(String file1, String file2) throws IOException { StringBuffer ret = new StringBuffer(1024); FileReader f1 = new FileReader(file1); FileReader f2 = new FileReader(file2); Map threadsMap1 = getThreads(f1); Map threadsMap2 = getThreads(f2); String[] keys = (String[])threadsMap1.keySet().toArray(new String[threadsMap1.size()]); for (int i=0; i < keys.length; i++) { String key = keys[i]; ThreadUtility t1 = (ThreadUtility)threadsMap1.get(key); ThreadUtility t2 = (ThreadUtility)threadsMap2.get(key); if (t2 != null) { ret.append("Thread '").append(key).append("' (").append(t1.getName()).append(") exists on both stack traces same='"); if (t1.isUnchanged(t2)) { ret.append("true'\n"); ret.append(t1); } else ret.append("false'\n"); } } return ret.toString(); } private boolean isUnchanged(ThreadUtility other) { if (other == null) return false; if (!this.threadId.equals(other.getThreadId())) return false; if (this.stack.length != other.getStack().length) return false; if (!this.head.equals(other.getHead())) return false; String[] otherStack = other.getStack(); for (int i=0; i < otherStack.length; i++) { if (!this.stack[i].equals(otherStack[i])) return false; } return true; } // "pool-1-thread-372" prio=10 tid=000638e0 nid=33621 lwp_id=1653384 in Object.wait() [2f6f1000..2f6f1578] // "XmlBlaster.SOCKET" daemon prio=10 tid=00ea17b8 nid=33247 lwp_id=1646483 runnable [2ef62000..2ef62878] public void setHead(String head) { this.head = head; StringTokenizer tokenizer = new StringTokenizer(head, " "); this.name = getNextToken(tokenizer); String txt = getNextToken(tokenizer); if ("daemon".equals(txt)) { this.daemon = true; this.prio = Integer.parseInt(getNextToken(tokenizer)); } else this.prio = Integer.parseInt(txt); this.threadId = getNextToken(tokenizer); this.nId = getNextToken(tokenizer); this.lwpId = getNextToken(tokenizer); this.tail = getTail(tokenizer); } public String getHead() { return head; } public boolean isDaemon() { return daemon; } public String getLwpId() { return lwpId; } public String getName() { return name; } public String getNId() { return nId; } public int getPrio() { return prio; } public String getTail() { return tail; } public String[] getStack() { return stack; } public void setStack(String[] stack) { this.stack = stack; } public String getThreadId() { return threadId; } public String toString() { StringBuffer ret = new StringBuffer(512); ret.append(this.head).append("\n"); for (int i=0; i < this.stack.length; i++) ret.append(this.stack[i]).append("\n"); return ret.toString(); } public static void main(String[] args) { if (args.length < 2) { System.err.println("usage: java " + ThreadUtility.class.getName() + " stackFilename1 stackFilename2"); System.exit(-1); } String file1 = args[0]; String file2 = args[1]; try { System.out.println(ThreadUtility.dumpUnchangedThreads(file1, file2)); } catch (Exception ex) { ex.printStackTrace(); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -