死锁发生:两个或多个线程之间,互相持有对方需要的锁,而永久处于阻塞状态
一、手写死锁代码:
public class DeadLockSample extendsThread {privateString first;privateString second;publicDeadLockSample(String name, String first, String second) {super(name);this.first =first;this.second =second;
}
@Overridepublic voidrun() {synchronized(first) {
System.out.println(this.getName() + " obtained:" +first);try{
TimeUnit.SECONDS.sleep(1);synchronized(second){
System.out.println(this.getName() + " obtained:" +second);
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}public static void main(String[] args) throwsInterruptedException{
String lockA= "lockA";
String lockB= "lockB";
DeadLockSample deadLockSample1= new DeadLockSample("thread1",lockA,lockB);
DeadLockSample deadLockSample2= new DeadLockSample("thread2",lockB,lockA);
deadLockSample1.start();
deadLockSample2.start();
deadLockSample1.join();
deadLockSample2.join();
}
}
二、死锁产生的四个条件:
互斥:共享资源X和Y只能被一个线程占用
占有且等待:线程T1已经获取共享资源X,在等待共享资源Y的时候,不释放共享资源X
不可抢占:其他线程不能强行抢占线程T1占有的资源
循环等待:线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,这就是循环等待。
三、死锁定位:
jps -l
jstack pid
Found one Java-level deadlock:
=============================
"thread2":
waiting to lock monitor 0x00007fa34c016148 (object 0x00000007957fc7d0, a java.lang.String),
which is held by "thread1"
"thread1":
waiting to lock monitor 0x00007fa34c016358 (object 0x00000007957fc808, a java.lang.String),
which is held by "thread2"
Java stack information for the threads listed above:
===================================================
"thread2":
at com.example.demo.javaLession.lession18.DeadLockSample.run(DeadLockSample.java:41)
- waiting to lock <0x00000007957fc7d0> (a java.lang.String)
-locked <0x00000007957fc808> (a java.lang.String)
"thread1":
at com.example.demo.javaLession.lession18.DeadLockSample.run(DeadLockSample.java:41)
-waiting to lock <0x00000007957fc808> (a java.lang.String)
- locked <0x00000007957fc7d0> (a java.lang.String)
Found 1 deadlock.
四、预防死锁:
破坏占有且等待条件:保证一次申请所有的资源。
破坏不可抢占条件:synchronized无法做到,synchronized申请不到资源直接进入阻塞状态。
java.util.concurrent Lock可以解决此问题
破坏循环等待条件:需要对资源进行排序,然后按序申请资源
五、修复死锁
发生死锁无法在线解决,必须重启,修正程序本身的问题