死锁发生:两个或多个线程之间,互相持有对方需要的锁,而永久处于阻塞状态
一、手写死锁代码:
public class DeadLockSample extends Thread { private String first; private String second; public DeadLockSample(String name, String first, String second) { super(name); this.first = first; this.second = second; } @Override public void run() { 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) throws InterruptedException{ 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可以解决此问题
破坏循环等待条件:需要对资源进行排序,然后按序申请资源
五、修复死锁
发生死锁无法在线解决,必须重启,修正程序本身的问题