大家都知道多线程并发的时候,我们一般会用到锁。但是锁用不好,就会导致死锁。那么,死锁是如何产生的呢?
一般造成死锁必须同时满足如下4个条件:
- 互斥条件:线程使用的资源必须至少有一个是不能共享的。
- 请求与保持条件:至少有一个线程必须持有一个资源并且正在等待获取一个当前被其他线程持有的资源。
- 非剥夺条件:分配的资源不能从相应的线程中被强制剥夺。
- 循环等待条件:第一个线程等待其他线程,后者又在等待第一个线程。
接下来我们来看一段手写的死锁代码
package com.sync;
/**
* 手写一个死锁
*
* @author 小辉GE/小辉哥
* <p>
* 2019年8月10日 下午18:30:00
*/
public class DeadLock {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
Runner r1 = new Runner(obj1, obj2, 5000);
Runner r2 = new Runner(obj2, obj1, 5000);
new Thread(r1, "r1").start();
new Thread(r2, "r2").start();
}
}
class Runner implements Runnable {
private Object o1;
private Object o2;
private int sleepTime;
public Runner(Object o1, Object o2, int sleepTime) {
this.o1 = o1;
this.o2 = o2;
this.sleepTime = sleepTime;
}
public void run() {
System.out.println("当前线程" + Thread.currentThread().getName() + "获得锁");
synchronized (o1) {
try {
// 这里主要是放大效果
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println();
}
}
}
}
测试输出结果如下:
结果分析:
其实我们不难看出,线r1启动时候先获得obj1对象锁且需要获得obj2对象锁,线程r2启动时先获得obj2对象锁且需要获取obj1对象锁,这就同时满足了死锁的条件,也就出现了死锁。
以上代码仅供参考,如有不当之处,欢迎指出!!!
更多干货,欢迎大家关注和联系我。期待和大家一起更好的交流、探讨技术!!!