多线程时有可能遇到:程序一直不停,也不报错,只是靠console不能获取到足够的信息,怀疑死锁或其它情况了,这时候我们就可以找jconsole帮忙(jconsole是JDK内置的小工具)。
连接
以eclipse为例,在工具栏 > run as(debug as) > runconfigurations 里加入以下三行参数:
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
e.g.
查看引擎ip (e.g. 本机)
如果JDK path等之类的已经配好,直接在cmd里拷jconsole来启动
首先程序要先启动了,然后就可以用jconsole来连了(远程进程:<ip>:9999)
jconsole中的一些选项,都很简单,标注一下,大家弄弄就知道怎么用了(如:最左下角可以filter线程名字,“检测死锁”则可以一键检测,可有用了~~)
应用例子
案例中有条语句一运行就无限等待了public void stopCheckStateTask() {
<span style="white-space:pre"> </span>logger.debug("stopCheckStateTask~~~:" + Thread.currentThread().getName());
<span style="white-space:pre"> </span>lock.lock(); // 无限等待
<span style="white-space:pre"> </span>try {...
首先按“检测死锁”,结果没有发现死锁。随之找出语句正在运行的线程,如图
注意:上图中的ReetrantLock$NonfairSync表明是用了ReetrantLock非公平锁机制
该线程进入Waiting状态,“拥有者”是它正在等待的对方线程,即pool-18-tread-2。不过这个case中的pool-18-tread-2是找不到的,证明此时没有运行,我们在eclipse的debug stack trace中找到这个thread,并在怀疑有问题的语句中加上断点,就出现了
通进分析,发现这个例子中的问题不是死锁,而是有线程出现无限等待了,原因就在于有一直有scheduler弄出来的线程排在了该线程前面运行,解决方法之一是使用公平锁。
protected Lock lock = new ReentrantLock(true); // 公平锁