스레드를 모니터링하는 3가지 방법

51347 단어
1. JDK 명령줄 도구 - jstack
jps -l
현재 실행 스레드 조회
barry@Y430P:~/data/projects/test$ jps -l
18339 /usr/share/dbeaver//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar
9046 org.jetbrains.jps.cmdline.Launcher
16087 com.intellij.idea.Main
9049 test.threadjava.ThreadGroupTest
9131 sun.tools.jps.Jps
27133 org.jetbrains.jps.cmdline.Launcher
6606 org.jetbrains.plugins.scala.nailgun.NailgunRunner

jstack -[operation] pid
여기서 operation:
-F: jstack pid가 응답하지 않을 때 -F를 사용하여 dump 스레드 정보 강제
-m: 자바 스레드 스택과 로컬 스레드 스택 인쇄
-l: 장기 감청
barry@Y430P:~/data/projects/test$ jstack 9049
2019-01-02 16:33:25
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode):

"Attach Listener" #17 daemon prio=9 os_prio=0 tid=0x00007f03fc001000 nid=0x23e3 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #16 prio=5 os_prio=0 tid=0x00007f044c00e000 nid=0x235c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread 4" #15 prio=5 os_prio=0 tid=0x00007f044c4a0800 nid=0x2388 waiting on condition [0x00007f0411c36000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 3" #14 prio=5 os_prio=0 tid=0x00007f044c49f000 nid=0x2387 waiting on condition [0x00007f0411d37000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 2" #13 prio=5 os_prio=0 tid=0x00007f044c49d000 nid=0x2386 waiting on condition [0x00007f0411e38000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 1" #12 prio=5 os_prio=0 tid=0x00007f044c49b800 nid=0x2385 waiting on condition [0x00007f0411f39000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 0" #11 prio=5 os_prio=0 tid=0x00007f044c49a000 nid=0x2384 waiting on condition [0x00007f041203a000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x00007f044c476800 nid=0x2382 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #9 daemon prio=9 os_prio=0 tid=0x00007f044c461800 nid=0x2381 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #8 daemon prio=9 os_prio=0 tid=0x00007f044c45f800 nid=0x2380 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=0 tid=0x00007f044c45d000 nid=0x237f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=0 tid=0x00007f044c45b800 nid=0x237e waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=0 tid=0x00007f044c459800 nid=0x237d runnable [0x00007f0412958000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        - locked <0x000000076d0bba70> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        - locked <0x000000076d0bba70> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f044c20a000 nid=0x237c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f044c1d7800 nid=0x2374 in Object.wait() [0x00007f0412fee000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076ce08ed0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x000000076ce08ed0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f044c1d2800 nid=0x2373 in Object.wait() [0x00007f04130ef000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076ce06bf8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x000000076ce06bf8> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=0 tid=0x00007f044c1cb000 nid=0x2370 runnable 

 
2.JDK1.7 이후 명령줄 도구 - jcmd
JDK에서 1.7 다음에 추가된 명령행 도구 jcmd는 다기능 도구로 더미를 내보내고 자바 프로세스를 보며 루트 정보를 내보내고 GC를 실행할 수 있습니다.
jcmd -l 
현재 시스템의 모든 Java 가상 머신을 나열합니다.
barry@Y430P:~/data/projects/test$ jcmd -l
18339 /usr/share/dbeaver//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar -os linux -ws gtk -arch x86_64 -showsplash -launcher /usr/share/dbeaver/dbeaver -name Dbeaver --launcher.library /usr/share/dbeaver//plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.551.v20171108-1834/eclipse_1630.so -startup /usr/share/dbeaver//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar --launcher.overrideVmargs -exitdata 17800b -vm /usr/bin/java -vmargs -XX:+IgnoreUnrecognizedVMOptions -Xms64m -Xmx1024m -jar /usr/share/dbeaver//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar
9493 sun.tools.jcmd.JCmd -l
9046 org.jetbrains.jps.cmdline.Launcher /home/barry/app/idea2018/lib/guava-21.0.jar:/home/barry/app/idea2018/lib/resources_en.jar:/home/barry/app/idea2018/lib/commons-codec-1.9.jar:/home/barry/app/idea2018/lib/nanoxml-2.2.3.jar:/home/barry/app/idea2018/lib/protobuf-java-3.0.0.jar:/home/barry/app/idea2018/lib/lz4-java-1.3.jar:/home/barry/app/idea2018/lib/idea_rt.jar:/home/barry/app/idea2018/lib/jna.jar:/home/barry/app/idea2018/lib/asm-all.jar:/home/barry/app/idea2018/lib/httpclient-4.5.2.jar:/home/barry/app/idea2018/lib/netty-all-4.1.13.Final.jar:/home/barry/app/idea2018/lib/util.jar:/home/barry/app/idea2018/lib/jgoodies-forms.jar:/home/barry/app/idea2018/lib/commons-logging-1.2.jar:/home/barry/app/idea2018/lib/javac2.jar:/home/barry/app/idea2018/lib/aether-1.1.0-all.jar:/home/barry/app/idea2018/lib/snappy-in-java-0.5.1.jar:/home/barry/app/idea2018/lib/oro-2.0.8.jar:/home/barry/app/idea2018/lib/jna-platform.jar:/home/barry/app/idea2018/lib/httpcore-4.4.5.jar:/home/barry/app/idea2018/lib/log4j.jar:/home/barry/app/id
16087 com.intellij.idea.Main
9049 test.threadjava.ThreadGroupTest
27133 org.jetbrains.jps.cmdline.Launcher /home/barry/app/idea2018/lib/guava-21.0.jar:/home/barry/app/idea2018/lib/resources_en.jar:/home/barry/app/idea2018/lib/commons-codec-1.9.jar:/home/barry/app/idea2018/lib/nanoxml-2.2.3.jar:/home/barry/app/idea2018/lib/protobuf-java-3.0.0.jar:/home/barry/app/idea2018/lib/lz4-java-1.3.jar:/home/barry/app/idea2018/lib/idea_rt.jar:/home/barry/app/idea2018/lib/jna.jar:/home/barry/app/idea2018/lib/asm-all.jar:/home/barry/app/idea2018/lib/httpclient-4.5.2.jar:/home/barry/app/idea2018/lib/netty-all-4.1.13.Final.jar:/home/barry/app/idea2018/lib/util.jar:/home/barry/app/idea2018/lib/jgoodies-forms.jar:/home/barry/app/idea2018/lib/commons-logging-1.2.jar:/home/barry/app/idea2018/lib/javac2.jar:/home/barry/app/idea2018/lib/aether-1.1.0-all.jar:/home/barry/app/idea2018/lib/snappy-in-java-0.5.1.jar:/home/barry/app/idea2018/lib/oro-2.0.8.jar:/home/barry/app/idea2018/lib/jna-platform.jar:/home/barry/app/idea2018/lib/httpcore-4.4.5.jar:/home/barry/app/idea2018/lib/log4j.jar:/home/barry/app/id
6606 org.jetbrains.plugins.scala.nailgun.NailgunRunner 3200 4c70a862-3824-4418-8bb8-4097c167783d

 
jcmd 13 help 
jcmd 모든 도움말 문서 조회
barry@Y430P:~/data/projects/test$ jcmd 9049 help
9049:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help

For more information about a specific command use 'help '.

 
jcmd 13 help Thread.print
질의 Thread.print 도움말 문서
barry@Y430P:~/data/projects/test$ jcmd 9049 help Thread.print
9049:
Thread.print
Print all threads with stacktraces.

Impact: Medium: Depends on the number of threads.

Permission: java.lang.management.ManagementPermission(monitor)

Syntax : Thread.print [options]

Options: (options must be specified using the  or = syntax)
        -l : [optional] print java.util.concurrent locks (BOOLEAN, false)

 
jcmd 13 Thread.print
스레드 13의 명령 모니터링 실행
barry@Y430P:~/data/projects/test$ jcmd 9049 Thread.print
9049:
2019-01-02 16:41:00
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode):

"Attach Listener" #17 daemon prio=9 os_prio=0 tid=0x00007f03fc001000 nid=0x23e3 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #16 prio=5 os_prio=0 tid=0x00007f044c00e000 nid=0x235c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread 4" #15 prio=5 os_prio=0 tid=0x00007f044c4a0800 nid=0x2388 waiting on condition [0x00007f0411c36000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 3" #14 prio=5 os_prio=0 tid=0x00007f044c49f000 nid=0x2387 waiting on condition [0x00007f0411d37000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 2" #13 prio=5 os_prio=0 tid=0x00007f044c49d000 nid=0x2386 waiting on condition [0x00007f0411e38000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 1" #12 prio=5 os_prio=0 tid=0x00007f044c49b800 nid=0x2385 waiting on condition [0x00007f0411f39000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Thread 0" #11 prio=5 os_prio=0 tid=0x00007f044c49a000 nid=0x2384 waiting on condition [0x00007f041203a000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at test.threadjava.ThreadGroupTest.run(ThreadGroupTest.java:18)
        at java.lang.Thread.run(Thread.java:748)

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x00007f044c476800 nid=0x2382 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #9 daemon prio=9 os_prio=0 tid=0x00007f044c461800 nid=0x2381 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #8 daemon prio=9 os_prio=0 tid=0x00007f044c45f800 nid=0x2380 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=0 tid=0x00007f044c45d000 nid=0x237f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=0 tid=0x00007f044c45b800 nid=0x237e waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=0 tid=0x00007f044c459800 nid=0x237d runnable [0x00007f0412958000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        - locked <0x000000076d0bba70> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        - locked <0x000000076d0bba70> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f044c20a000 nid=0x237c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

 
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 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 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.(URL.java:622)
java.net.URL.(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)

  
주의: 세 번째 방식은 단일 라인의 상황만 감시하기에 적합하고 하위 라인을 감시하기에 적합하지 않다. 만약에 하위 라인이 있다면 이런 방식을 사용하지 마십시오.흥미로운 것은 서브라인을 감시하면 어떤 상황이 나타날지 시험해 볼 수 있다.

좋은 웹페이지 즐겨찾기