Mar*_*rga 13 java profiler multithreading
我在Java中有一个方法可以调用其他几种方法.从固定线程池中的多个线程调用此方法.工作线程数与可用处理器(核心数)相同.
public void query() {
method1();
method2();
}
Run Code Online (Sandbox Code Playgroud)
当我使用VisualVM分析程序执行时,时间method1()和method2()时间非常短,但query()自我时间很长.但除了两个调用之外,该方法没有其他代码.有可能是内部的同步method1()和method2(),但没有明显的代码,我管了.
当我将池中的工作者数量减少到1时,这个自我时间几乎消失了.整个程序的单线程和多线程执行时间几乎相同.我认为这意味着我的方法query()正在等待某事.
没有死锁,执行完成得很好.这两种方法method1(),并method2()调用了很多其他的事情,包括在混淆罐库中的类,所以它是不容易的,我调试.但是query(),使用该方法直接从工作线程调用java.util.concurrent.ExecutorService.
针对正在运行的进程在级别3发出kill命令.所有线程都会将堆栈跟踪转储到标准输出,应用程序将继续运行.
kill -3 <pid>
Run Code Online (Sandbox Code Playgroud)
注意,您在控制台上看不到发出kill命令的任何内容.Java应用程序本身将具有输出.您可能需要检查日志,具体取决于应用程序重定向其输出的位置.
我在一个代理类中发现了问题,该代理类将另一个类包装在自定义锁定机制中。
我继续创建一系列线程转储。由于我使用 JVisualVM 进行分析,因此在此过程中我创建了一些线程转储。Ctrl+Break也有效,正如kill -3 <pid>Synesso 在他的回答中提到的那样。
我使用评论中提到的线程转储分析器来分析它们。我不知道首先要寻找什么,但由于 TDA 中对象和监视器的链接,我发现了如下内容:
"pool-9-thread-32" #304 prio=5 os_prio=0 tid=0x000000002a706800 nid=0x348c waiting for monitor entry [0x000000003f06e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.example.MyClass.method1(MyClass.java:400)
- waiting to lock <0x0000000680837b90> (a com.example.DifferentClass)
at com.example.MyClass.query(MyClass.java:500)
... omitted ...
at java.util.concurrent.FutureTask.run(FutureTask.java:270)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:618)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- <0x000000075bc59aa8> (a java.util.concurrent.ThreadPoolExecutor$Worker)
Run Code Online (Sandbox Code Playgroud)
DifferentClass扩展抽象MyClass,并且有一个来自method1()to 的调用DifferentClass,其中 DTO 对象被传递给一个执行大量处理、日志记录并最终保存到数据库的方法。在创建数据库处理类之一期间使用了代理类。
| 归档时间: |
|
| 查看次数: |
400 次 |
| 最近记录: |