Deadlock coding and location analysis
concept
Deadlock refers to the phenomenon of two or more processes waiting for each other due to competition for resources during the execution process. If there is no external interference, they will not be able to advance. If the resources are sufficient, the resource requests of the process can be satisfied, and the possibility of a deadlock is very low, otherwise it will fall into a deadlock due to contention for limited resources.
The cause of the deadlock
- Insufficient system resources
- The order in which the processes are running is not correct
- Misallocation of resources
Four necessary conditions for deadlock
- Mutually exclusive
- Solution: encapsulate mutually exclusive shared resources into simultaneous access
- Hold and wait
- Solution: When a process requests resources, it requires it not to occupy any other resources, that is, it must apply for all resources at once. This method will lead to low resource efficiency.
- Non-preemptive
- Solution: If the process cannot allocate resources immediately, it is required that it does not occupy any other resources, that is, it can only perform the allocation operation when it can obtain all the required resources at the same time
- Loop waiting
- Solution: Sort the resources and require the process to request the resources in order.
Deadlock code
We created a resource class, and then let two threads hold their own locks, and at the same time try to acquire others, there will be deadlock phenomenon
/**
* 死锁小Demo
* 死锁是指两个或多个以上的进程在执行过程中,
* 因争夺资源而造成一种互相等待的现象,
* 若无外力干涉那他们都将无法推进下去
*/
import java.util.concurrent.TimeUnit;
/**
* 资源类
*/
class HoldLockThread implements Runnable{
private String lockA;
private String lockB;
// 持有自己的锁,还想得到别人的锁
public HoldLockThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA) {
System.out.println(Thread.currentThread().getName() + "\t 自己持有" + lockA + "\t 尝试获取:" + lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB) {
System.out.println(Thread.currentThread().getName() + "\t 自己持有" + lockB + "\t 尝试获取:" + lockA);
}
}
}
}
public class DeadLockDemo {
public static void main(String[] args) {
String lockA = "lockA";
String lockB = "lockB";
new Thread(new HoldLockThread(lockA, lockB), "t1").start();
new Thread(new HoldLockThread(lockB, lockA), "t2").start();
}
}
As a result of running, the main thread cannot end
t1 自己持有lockA 尝试获取:lockB
t2 自己持有lockB 尝试获取:lockA
How to troubleshoot deadlocks
When we have a deadlock, we first need to use the jps command to view the running program
jps -l
We can see the DeadLockDemo class, which has been running
Use jstack to view stack information
jstack 7560 # 后面参数是 jps输出的该类的pid
The results obtained
Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x000000001cfc0de8 (object 0x000000076b696e80, a java.lang.String),
which is held by "t1"
"t1":
waiting to lock monitor 0x000000001cfc3728 (object 0x000000076b696eb8, a java.lang.String),
which is held by "t2"
Java stack information for the threads listed above:
===================================================
"t2":
at com.moxi.interview.study.Lock.HoldLockThread.run(DeadLockDemo.java:42)
- waiting to lock <0x000000076b696e80> (a java.lang.String)
- locked <0x000000076b696eb8> (a java.lang.String)
at java.lang.Thread.run(Thread.java:745)
"t1":
at com.moxi.interview.study.Lock.HoldLockThread.run(DeadLockDemo.java:42)
- waiting to lock <0x000000076b696eb8> (a java.lang.String)
- locked <0x000000076b696e80> (a java.lang.String)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
By looking at the last line, we see Found 1 deadlock, that is, there is a deadlock