一、什么是死锁
死锁指多个进程在运行过程中因争夺资源而造成的一种僵局,若进程处于这种状态时,若无外力作用,它们都无法再向前推进。
此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。
er
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
private void deadLock() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A) {
try { Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.println("1");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B) {
synchronized (A) {
System.out.println("2");
}
}
}
});
t1.start();
t2.start();
}
}
二、产生死锁的原因
1.竞争资源
1)可剥夺资源,指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺,CPU和主存均属于可剥夺性资源。
2)另一类资源是不可剥夺资源,当系统把这类资源分配给其他进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。
2.进程间推进顺序非法
三、死锁产生的必要条件
1.互斥:资源必须处于非共享模式,即一次只有一个进程可以使用。如果另一进程申请该资源,那么必须等待直到该资源被释放为止。
2占有并等待:一个进程至少应该占有一个资源,并等待另一资源,而该资源被其他进程所占有。
3.非抢占:资源不能被抢占。只能在持有资源的进程完成任务后,该资源才会被释放。
4.循环等待:有一组等待进程 {P0, P1,..., Pn}
, P0
等待的资源被 P1
占有,P1
等待的资源被 P2
占有,......,Pn-1
等待的资源被 Pn
占有,Pn
等待的资源被 P0
占有。
四、避免死锁的常用方法
1.避免一个线程同时获取多个锁
2.避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
3.尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
4.对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。