监控线程的3种方法
Posted barrywxx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了监控线程的3种方法相关的知识,希望对你有一定的参考价值。
1. JDK命令行工具 - jstack
jps -l 查询当前运行线程
jstack -[operation] pid
其中operation:
-F:当 jstack pid没有响应时,使用-F强制dump线程信息
-m:打印java线程栈和本地线程栈
-l:长期监听,
打印锁信息 jstack -l 13 >/tmp/deadlock.txt -l 会打印锁的附加信息。
2.JDK1.7以后的命令行工具-jcmd
在JDK1.7后新增的一个命令行工具jcmd,它是一个多功能工具,可以用它来导出堆,查看Java进程,导出线程信息,执行GC等。
jcmd -l
列出当前系统中的所有Java虚拟机
jcmd 13 help
查询jcmd所有帮助文档
jcmd 13 help Thread.print
查询Thread.print的帮助文档
jcmd 13 Thread.print
执行线程13的命令监控
3. 通过程序监控
Java版本实现:
1 import java.util.ArrayList; 2 import java.util.List; 3 4 /** 5 * 类功能描述: 6 * 7 * @author WangXueXing create at 18-12-26 下午2:28 8 * @version 1.0.0 9 */ 10 public class ThreadMonitor extends Thread { 11 private Logger LOGGER = LoggerFactory.getLogger(this.getClass()); 12 private volatile boolean finished = false; 13 private Thread currentThread; 14 public ThreadMonitor(Thread currentThread){ 15 this.currentThread = currentThread; 16 } 17 18 @Override 19 public void run() { 20 while (!this.finished) { 21 StackTraceElement[] stackElements = this.currentThread.getStackTrace(); 22 List<String> list = new ArrayList<>(); 23 for(StackTraceElement stackElement : stackElements){ 24 list.add(stackElement.toString()+" "); 25 } 26 LOGGER.info(list.toString()); 27 28 try { 29 Thread.sleep(1000); 30 } catch (InterruptedException e) { 31 e.printStackTrace(); 32 } 33 } 34 } 35 36 public void setFinished(boolean finished) { 37 this.finished = finished; 38 } 39 40 public void doSomething(){ 41 List<Integer> list = new ArrayList<>(); 42 for(int i=0; i<=100000000; i++){ 43 list.add(i); 44 } 45 } 46 47 public static void main(String[] args){ 48 Thread currentThread = Thread.currentThread(); 49 ThreadMonitor tm = new ThreadMonitor(currentThread); 50 tm.start(); 51 tm.doSomething(); 52 tm.setFinished(true); 53 } 54 }
Scala版本实现,Scala还是强大些,比Java更加灵活,可以传入代码块:
1 import org.slf4j.LoggerFactory 2 3 /** 4 * 类功能描述:线程监控器 5 * 6 * @author WangXueXing create at 18-12-25 下午3:44 7 * @version 1.0.0 8 */ 9 object ThreadMonitor { 10 val LOGGER = LoggerFactory.getLogger(getClass) 11 /** 12 * 线程监控器 13 * 注意,当代码块里有子线程,可能无法监控到对应线程日志 14 * @param currentThread 当前执行线程 15 * @param intervalTime 打印线程堆栈的间隔时间, 单位为毫秒;选传,默认为1秒 16 * @param codeBlock 要监控的代码块 17 * @tparam T 18 */ 19 def threadMonitor[T](currentThread: Thread, intervalTime: Option[Long]=None) (codeBlock: => T) { 20 //set the real real interval time as 1s if the param intervalTime is None 21 val realIntervalTime = intervalTime match { 22 case Some(x) => x 23 case None => 1000 24 } 25 @volatile 26 var flag = false 27 val t = new Thread(() => { 28 while (!flag) { 29 val stackElements = currentThread.getStackTrace 30 LOGGER.info(stackElements.map(_.toString).mkString(" ")) 31 Thread.sleep(realIntervalTime) 32 } 33 }) 34 t.start() 35 try{ 36 codeBlock 37 } finally { 38 flag = true 39 } 40 } 41 }
调用监控线程:
import test.thread.ThreadMonitor /** * 类功能描述://TODO * * @author WangXueXing create at 18-12-27 下午1:18 * @version 1.0.0 */ object Test { def doSomething(): Unit ={ Range.apply(1, 100000000).map(_); } def main(args: Array[String]): Unit = { val currentThread = Thread.currentThread() ThreadMonitor.threadMonitor(currentThread){ Test.doSomething(); } } }
运行输出结果如下:
13:23:07.955 [Thread-0] INFO test.thread.ThreadMonitor$ - sun.net.www.protocol.file.Handler.parseURL(Handler.java:67) java.net.URL.<init>(URL.java:622) java.net.URL.<init>(URL.java:490) sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:1260) sun.misc.URLClassPath.getResource(URLClassPath.java:239) java.net.URLClassLoader$1.run(URLClassLoader.java:365) java.net.URLClassLoader$1.run(URLClassLoader.java:362) java.security.AccessController.doPrivileged(Native Method) java.net.URLClassLoader.findClass(URLClassLoader.java:361) java.lang.ClassLoader.loadClass(ClassLoader.java:424) sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) java.lang.ClassLoader.loadClass(ClassLoader.java:357) test.Test$.doSomething(Test.scala:14) test.Test$.$anonfun$main$1(Test.scala:20) test.Test$$$Lambda$1/33524623.apply$mcV$sp(Unknown Source) scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12) test.thread.ThreadMonitor$.threadMonitor(ThreadMonitor.scala:38) test.Test$.main(Test.scala:20) test.Test.main(Test.scala) 13:23:10.999 [Thread-0] INFO test.thread.ThreadMonitor$ - scala.collection.immutable.Range.foreach(Range.scala:154) scala.collection.TraversableLike.map(TraversableLike.scala:233) scala.collection.TraversableLike.map$(TraversableLike.scala:226) scala.collection.AbstractTraversable.map(Traversable.scala:104) test.Test$.doSomething(Test.scala:14) test.Test$.$anonfun$main$1(Test.scala:20) test.Test$$$Lambda$1/33524623.apply$mcV$sp(Unknown Source) scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12) test.thread.ThreadMonitor$.threadMonitor(ThreadMonitor.scala:38) test.Test$.main(Test.scala:20) test.Test.main(Test.scala) 13:23:14.129 [Thread-0] INFO test.thread.ThreadMonitor$ - scala.collection.immutable.Range.foreach(Range.scala:154) scala.collection.TraversableLike.map(TraversableLike.scala:233) scala.collection.TraversableLike.map$(TraversableLike.scala:226) scala.collection.AbstractTraversable.map(Traversable.scala:104) test.Test$.doSomething(Test.scala:14) test.Test$.$anonfun$main$1(Test.scala:20) test.Test$$$Lambda$1/33524623.apply$mcV$sp(Unknown Source) scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12) test.thread.ThreadMonitor$.threadMonitor(ThreadMonitor.scala:38) test.Test$.main(Test.scala:20) test.Test.main(Test.scala) 13:23:20.027 [Thread-0] INFO test.thread.ThreadMonitor$ - scala.collection.immutable.Range.foreach(Range.scala:154) scala.collection.TraversableLike.map(TraversableLike.scala:233) scala.collection.TraversableLike.map$(TraversableLike.scala:226) scala.collection.AbstractTraversable.map(Traversable.scala:104) test.Test$.doSomething(Test.scala:14) test.Test$.$anonfun$main$1(Test.scala:20) test.Test$$$Lambda$1/33524623.apply$mcV$sp(Unknown Source) scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12) test.thread.ThreadMonitor$.threadMonitor(ThreadMonitor.scala:38) test.Test$.main(Test.scala:20) test.Test.main(Test.scala) 13:23:23.620 [Thread-0] INFO test.thread.ThreadMonitor$ - scala.collection.immutable.Range.foreach(Range.scala:154) scala.collection.TraversableLike.map(TraversableLike.scala:233) scala.collection.TraversableLike.map$(TraversableLike.scala:226) scala.collection.AbstractTraversable.map(Traversable.scala:104) test.Test$.doSomething(Test.scala:14) test.Test$.$anonfun$main$1(Test.scala:20) test.Test$$$Lambda$1/33524623.apply$mcV$sp(Unknown Source) scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12) test.thread.ThreadMonitor$.threadMonitor(ThreadMonitor.scala:38) test.Test$.main(Test.scala:20) test.Test.main(Test.scala)
以上是关于监控线程的3种方法的主要内容,如果未能解决你的问题,请参考以下文章