死锁

/ 多线程 / 没有评论 / 255浏览

死锁是在开发多线程时才会遇到的。原因就是不同的线程都在等待其它线程释放锁,而其它线程由于一些原因迟迟没有释放,这就造成了所有的线程都开始等待程序出现了假死的现象。说白了这就是一个BUG。我们用下面简单的程序来模拟一下死锁发生的现象。

/**
* 用户登录
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo {

private String lock1 = new String();
private String lock2 = new String();

public void userLogin(String username) {
if ("admin".equals(username)) {
synchronized (lock1) {
System.out.println(String.format("lock1: %s\tthread: %s", username, Thread.currentThread().getName()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println(String.format("lock2: %s\tthread: %s", username, Thread.currentThread().getName()));
}
}
} else {
synchronized (lock2) {
System.out.println(String.format("lock2: %s\tthread: %s", username, Thread.currentThread().getName()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println(String.format("lock1: %s\tthread: %s", username, Thread.currentThread().getName()));
}
}
}
}

}
/**
* 管理用户请求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestAdmin extends Thread {

private Userinfo userinfo;

public RequestAdmin(Userinfo userinfo) {
this.userinfo = userinfo;
}

@Override
public void run() {
userinfo.userLogin("admin");
}
}
/**
* 用户请求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestUser extends Thread {

private Userinfo userinfo;

public RequestUser(Userinfo userinfo) {
this.userinfo = userinfo;
}

@Override
public void run() {
userinfo.userLogin("user");
}
}
lock2: user	thread: Thread-1
lock1: admin	thread: Thread-0

发现程序居然不输出了,这就是我们上面所说的死锁现象。所有线程都在等着对方释放锁 ,所以就会出现这种程序假死情况。如果真出线了死锁我们应该怎么解决呢?因为在多线程中是不太好查找问题所在的。别担心Java为我们提供了一个命令来帮我们快速的查找问题所在。下面的方法就是如果真有死锁发生,我们怎么快速查看问题。

我们用windows系统来演示。具体的步骤如下:

  1. 我们用cmd进入系统的命令窗口。
  2. 将目录切换到Jdk安装目录的bin下。
  3. 运行Java自带的jps命令
  4. 运行jstack -l 进程id

下面看我具体的执行效果:

121212.jpg

121212.jpg

121212.jpg

看到没这个命令直接帮我们定位到了代码中的某一行了,很方便我们查找问题有没有。如果以后在开发多线程中果真遇到了死锁问题,那么我们就可以用上述的方法快速定位问题。