当我们编写java程序时,由于不合理的设计,可能会出现程序死循环/死锁问题。
下面我就以程序的死锁为例,来进行分析
我编写的测试类是Run类
1.查找Run类对应的PID,使用命令:ps -ef | grep Run
lupeng 6765 4121 0 13:52 ? 00:00:00 /opt/java/jdk1.8.0_101/bin/java -Dfile.encoding=UTF-8 -classpath /home/lupeng/java_development/MultiThread/bin Run
lupeng 6795 2766 0 13:53 pts/0 00:00:00 grep --color=auto Run
2.利用java自带的工具jstack进行分析
jstack 6765
结果如下
Java stack information for the threads listed above:
===================================================
"Thread-1":
at DeadThread.run(DeadThread.java:37)
- waiting to lock <0x00000000ec1df068> (a java.lang.Object)
- locked <0x00000000ec1df078> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at DeadThread.run(DeadThread.java:21)
- waiting to lock <0x00000000ec1df078> (a java.lang.Object)
- locked <0x00000000ec1df068> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
deadlock说明出现死锁问题。
Thread-1 已经获得了锁<0x00000000ec1df078>,同时等待锁<0x00000000ec1df078>
Thread-0已经获得了锁<0x00000000ec1df078>,同时等待锁<0x00000000ec1df078>
一次发生了死锁问题。
即
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007fefcc003828 (object 0x00000000ec1df068, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007fefcc006218 (object 0x00000000ec1df078, a java.lang.Object),
which is held by "Thread-1"
那么到底时什么地方出现了死锁问题呢?
我们再来分析下
Java stack information for the threads listed above:
===================================================
"Thread-1":
at DeadThread.run(DeadThread.java:37)
- waiting to lock <0x00000000ec1df068> (a java.lang.Object)
- locked <0x00000000ec1df078> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at DeadThread.run(DeadThread.java:21)
- waiting to lock <0x00000000ec1df078> (a java.lang.Object)
- locked <0x00000000ec1df068> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
其中有一行是at DeadThread.run(DeadThread.java:37)
说明Thread-1实在DeadThread类的37行处发生死锁
其中at DeadThread.run(DeadThread.java:21)
说明Thread-0实在DeadThread类的21行处发生死锁
接下来我们定位到具体代码:
public class DeadThread implements Runnable{
public String username;
public Object lock1 = new Object();
public Object lock2 = new Object();
@Override
public void run() {
// TODO Auto-generated method stub
if(username.equals("a")){
synchronized (lock1) {
try {
System.out.println("username = "+username);
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("按lock1->lock2的顺序执行代码");
}
}
}
if(username.equals("b")){
synchronized (lock2) {
try{
System.out.println("username = "+username);
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("按lock2->lock1顺序执行代码");
}
}
}
}
public void setFlag(String username){
this.username=username;
}
}
从而定位到死锁发生的原因,及具体位置:
Thread-0获得了锁lock1,接下来期望获得锁lock2,(20)
但是此时Thread-1获得了锁lock2,接下来期望获得锁lock2,(37)
因而发生了死锁。