Guava 测试1
题目描述 :http://fresh.qunar.com/pages/viewpage.action?pageId=5570576
jvm提供了一个jstack的工具,可以把该jvm中运行的线程堆栈导出,具体见j.stack文件 比如 "DubboServerHandler-192.168.6.96:20880-thread-143" daemon prio=10 tid=0x00007f3d8006d000 nid=0x1807 waiting on condition [0x00007f3d67cfa000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00007f3f7c16b630> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:422) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323) at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:857) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619) DubboServerHandler-192.168.6.96:20880-thread-143为线程的名字,tid为线程id ,java.lang.Thread.State: WAITING,WAITING为线程状态 waiting on condition [0x00007f3d67cfa000]表示该线程waiting在tid=0x00007f3d67cfa000的线程上 请写一个程序,解析出线程名,线程id,线程状态,以及哪些线程wait在同一个condition上 。就是说匹配“waiting on condition”的线程进行统计。 输出结果按照等待同一个condition的线程数从大到小排序。 输出格式如下: condition id,count: 线程id|线程名|线程状态 线程id|线程名|线程状态 线程id|线程名|线程状态 condition id,count: 线程id|线程名|线程状态 线程id|线程名|线程状态 ……GuaExam2.java
package libinchen; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class GuaExam2 { public static Map<String, Integer> m1 = Maps.newHashMap(); // String 中存储的是 condition_id public static Map<String, List<StringBuffer>> m2 = Maps.newHashMap(); // StringBuffer 中存储的是字符串 "线程 id | 线程名 | 线程状态" private static void getRightLine(File f1) throws IOException { BufferedReader br = new BufferedReader(new FileReader(f1)); String strE1 = "waiting on condition ["; // 匹配 String str; while ((str = br.readLine()) != null) { int ks = str.indexOf(strE1); // 找到符合条件的行 if (ks != -1) { // 代表找到 E1 的位置 getTwoMap(str, br.readLine(), ks, strE1.length()); } } } public static void p(Object o) { System.out.println(o); } public static void getTwoMap(String first, String second, int begin, int sLen) { // 分析符合条件的行,提取出来 String seTid = "tid=", sNameEnd = "\" "; String E2 = "java.lang.Thread.State: "; String conTid, sTid, sName, sState; conTid = first.substring(begin + sLen, begin + sLen + 18); // 提取构造 condition,tid if (!m1.containsKey(conTid)) { m1.put(conTid, 1); } else { int freq = m1.get(conTid); m1.put(conTid, freq + 1); } // 构造 Map m1 int ks = first.indexOf(seTid); sTid = first.substring(ks + seTid.length(), ks + seTid.length()+ 18); // 构造 tid ks = first.indexOf(sNameEnd); sName = first.substring(1, ks); // 构造 线程名 : sName StringBuffer son = new StringBuffer(); son.append(sTid).append("|").append(sName).append("|"); ks = second.indexOf(E2); if (ks != -1) { String tmp = second.substring(ks + E2.length()); for (int i = 0; i < tmp.length(); i++) { if (tmp.charAt(i) == ' ') { break; } son.append(tmp.charAt(i)); } } if (!m2.containsKey(conTid)) { List<StringBuffer> kl = Lists.newArrayList(); kl.add(son); m2.put(conTid, kl); } else { List<StringBuffer> kl = m2.get(conTid); kl.add(son); m2.put(conTid, kl); } } public static Map sortByValue(Map<String, Integer> map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) o2).getValue()) .compareTo(((Map.Entry) o1).getValue()); } }); Map result = Maps.newLinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } static int lineCount = 0; /* Main */ public static void startMain() throws IOException { getRightLine(new File("/home/mxw/j.stack")); //p(GuaExam2.class.getClass().getResource("/j.stack").getPath()); //p(GuaExam2.class.getClass().getResource("/").getPath()); //File file = new File(GuaExam2.class.getClass().getResource("/").getPath() + "result.txt"); File file = new File("/home/mxw/examresult/libinchen.txt"); PrintStream out = new PrintStream(new FileOutputStream(file)); System.setOut(out); m1 = sortByValue(m1); for (String key : m1.keySet()) { p("conditionid:" + key + ",count:" + m2.get(key).size()); lineCount++; Iterator it = m2.get(key).iterator(); while (it.hasNext()) { p(it.next()); lineCount++; } } //p(lineCount); } }Exam.java
package libinchen; import java.io.File; import java.io.IOException; public class Exam { public static void exam() { GuaExam2 analyse = new GuaExam2(); try { analyse.startMain(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* public static void main(String[] args) throws IOException { Exam.exam(); } */ }pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qunar.fresh</groupId> <artifactId>Exam1</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Exam1</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.1</version> <scope>test</scope> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>15.0</version> </dependency> </dependencies> </project>