线程阻塞

本文介绍如何利用JDK自带工具监控线程活动并检测线程间的死锁情况。通过设置JMX参数,可以远程监控Java应用程序的线程状态。使用jconsole进行线程监控,并借助FullThreadDump工具检查线程死锁。

这几天碰到的report engine的问题,曾经怀疑是线程间死锁,所以也顺带研究了一把检查线程间死锁的方法。
JDK1.4及更早版本,没有更好的方法,就是在停止的命令行界面下敲Ctrl+Break或者Ctrl+\,打印当前的stack trace,然后根据stack trace里面的信息来分析。
JDK1.5及后续版本有个比较大的改进,就是提供了比较好的JMX支持,也提供了诸如jconsole(用于监控线程)和FullThreadDump(用于检查线程间是否有死锁)。
比较复杂的使用方法,可以查看相关文档,这里写一种快速使用的方法,应该是比较常用的。
假设我们要执行的类是com.ebay.datatools.reporting.engine.ReportEngine,它在执行过程中会生成一些线程,然后我们要做的就是监控它的所有线程以及检查这些线程之间是否有死锁。
首先,我们要把执行这个类的命令由:
java com.ebay.datatools.reporting.engine.ReportEngine
改为
java -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false com.ebay.datatools.reporting.engine.ReportEngine
区别就是其中添加了三个jmxremote相关的设置。
然后,我们可以直接的命令行下输入jconsole,会出现一个swing做的界面,上面的Port输入1090,用户名/密码留空,就可以和com.ebay.datatools.reporting.engine.ReportEngine的执行进程连接上了。然后就可以看它相关的信息了。
检查死锁的话,就是在命令行下输入:
java -cp FullThreadDump.jar FullThreadDump localhost:1090
FullThreadDump就会开始检查当前活跃的线程之间有没有死锁,并且把检查结果输出。
FullThreadDump的路径是JDK_HOME\demo\management\FullThreadDump,上述命令需要在FullThreadDump的目录下执行。

在Java中,有多种方法可以使线程进入阻塞状态: 1. **sleep()方法**:`sleep()`是Java中造成线程阻塞的方法,该方法会让当前线程暂停执行指定的时间,时间到后线程会自动恢复执行[^1]。 2. **wait()方法**:同样是造成线程阻塞的方法,通常与`synchronized`关键字配合使用。当线程调用对象的`wait()`方法时,它会释放对象的锁并进入等待状态,直到其他线程调用该对象的`notify()`或`notifyAll()`方法来唤醒它[^1]。 3. **LockSupport工具类**:可以实现更灵活的阻塞与唤醒。通过`LockSupport.park()`方法可以阻塞当前线程,通过`LockSupport.unpark(Thread thread)`方法可以唤醒指定线程。示例代码如下: ```java import java.util.concurrent.locks.LockSupport; public class ParkExample { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("Thread is parking..."); LockSupport.park(); // 阻塞当前线程 System.out.println("Thread un-parked!"); }); thread.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } LockSupport.unpark(thread); // 唤醒线程 } } ``` 4. **Condition接口的await()方法**:Java 5以后,可以使用`Lock`接口和`Condition`接口来实现等待/通知的高级用法。线程调用`Condition`的`await()`方法后会进入阻塞状态,直到其他线程调用`Condition`的`signal()`方法或`signalAll()`方法唤醒线程[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值