在多线程编程中,除了要解决数据访问的同步与互斥之外,还需要解决的重要问题就是多线程的死锁问题。
所谓死锁: 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外部处理作用,它们都将无限等待下去。
死锁形成的条件:
1.互斥条件:所谓互斥就是进程在某一时间内独占资源。
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
举个例子:
package TestDeadLock;
public class DealThread implements Runnable{
private String username;
private Object lock1=new Object();
private Object lock2=new Object();
public void setFlag(String username){
this.username=username;
}
@Override
public void run(){
if(username.equals("a")){
synchronized(lock1){
try {
System.out.println("username="+username);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(lock2){
System.out.println("按lock1->lock2代码顺序执行");
}
}
}
if(username.equals("b")){
synchronized(lock2){
try {
System.out.println("username="+username);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(lock1){
System.out.println("按lock2->lock1代码顺序执行");
}
}
}
}
}
package TestDeadLock;
public class Run {
public static void main(String[] args) {
try {
DealThread thread=new DealThread();
thread.setFlag("a");
Thread thread1=new Thread(thread);
thread1.start();
Thread.sleep(100);
thread.setFlag("b");
Thread thread2=new Thread(thread);
thread2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行Run.java代码
程序进入死锁状态,那么怎么查看死锁状态呢?
打开cmd,运行set java_home,找到jdk的安装路径,cd安装路径下的bin目录,运行jps命令可以查看当前java进程状态。
再使用命令 jstack -l 3908(Run状态的Java进程编号),结果如下:
监测到死锁现象!