#博学谷IT学习技术支持#
1原因
- 线程1 首先已经占有对象1,接着试图占有对象2
- 线程2 首先已经占有对象2,接着试图占有对象1
- 线程1 等待线程2释放对象2
- 线程2等待线程1释放对象1
这样线程1和线程2就会一直相互等待下去,(死锁)
2避免
1 避免一个线程同时获取多个锁
2、避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
3、尝试使用定时锁,使用lock.tryLock来代替使用内置锁。
4 如果项目是分布式也要考虑
3死锁原因代码复现
//自己随便写的一个类
@Data
public class LockObject {
private String name;
}
public class deadLock {
public static void main(String[] args) {
LockObject Jeni = new LockObject();//杰克
LockObject ruth = new LockObject();//露丝
Thread t1 = new Thread() {
@Override
public void run() {
synchronized (Jeni) {
try {
System.err.println("t1已经占有了杰克");
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("t1试图想占有露丝");
synchronized (ruth) {
System.err.println("t1已经同时占有露丝和杰克了");
}
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
synchronized (ruth) {
try {
System.err.println("t2已经占有了露丝");
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("t2试图想占有杰克");
synchronized (Jeni) {
System.err.println("t2已经同时占有露丝和杰克了");
}
}
}
};
t1.start();
t2.start();
}
}
4 解决
public class deadLock {
public static void main(String[] args) {
// LockObject Jeni = new LockObject();//杰克
// LockObject ruth = new LockObject();//露丝
//可重入锁
Lock JeniLock = new ReentrantLock();
Lock ruthLock = new ReentrantLock();
Thread t1 = new Thread() {
boolean Jeni = false;
boolean ruth = false;
@Override
public void run() {
try {
Jeni = JeniLock.tryLock(10, TimeUnit.SECONDS);//10秒 试图获取锁
if (Jeni) {
try {
System.err.println("t1已经占有了杰克");
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("t1试图想占有露丝");
try {
boolean ruth = ruthLock.tryLock(10, TimeUnit.SECONDS);//
if (ruth) {
System.err.println("t1已经同时占有露丝和杰克了");
}else {
System.err.println("t1只占有杰克,未占有露丝");
}
}finally {
if(ruth){ //这个可以在提前一些解锁 测试随便写了就
ruthLock.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
if(Jeni){
JeniLock.unlock();
}
}
}
};
Thread t2 = new Thread() {
boolean Jeni = false;
boolean ruth = false;
@Override
public void run() {
try {
ruth = ruthLock.tryLock(10, TimeUnit.SECONDS);//10秒 试图获取锁
if (ruth) {
try {
System.err.println("t2已经占有了露丝");
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("t2试图想占有杰克");
try {
Jeni = JeniLock.tryLock(10, TimeUnit.SECONDS);//10秒 试图获取锁
if (Jeni) {
System.err.println("t2已经同时占有露丝和杰克了");
}else{
System.err.println("t2只占有露丝,未占有杰克");
}
}finally {
if(Jeni){
JeniLock.unlock();
}
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(ruth){
ruthLock.unlock();
}
}
}
};
t1.start();
t2.start();
}
}