在Java中,死锁是一种编程情况,其中两个或多个线程被永久阻止。至少有两个线程和两个或更多资源将发生死锁情况。
如何避免死锁避免嵌套锁:当我们为多个线程提供锁时,主要会发生死锁。如果我们已经给一个线程,请避免给多个线程加锁。
避免不必要的锁定:我们只能锁定那些必需的成员。不必要地拥有锁可能导致死锁。
使用Thread.join():当一个线程正在等待另一个线程完成时,将出现死锁条件。如果发生这种情况,我们可以在执行所需的最长时间内使用Thread.join()。
示例public class DeadlockTest {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
t1.start();
Thread.sleep(2000);
t2.start();
Thread.sleep(2000);
}
}
class SyncThread implements Runnable {
private Object obj1;
private Object obj2;
public SyncThread(Object o1, Object o2){
this.obj1=o1;
this.obj2=o2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on " + obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on " + obj1);
work();
}
System.out.println(name + " released lock on " + obj1);
System.out.println(name + " acquiring lock on " + obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on " + obj2);
work();
}
System.out.println(name + " released lock on " + obj2);
System.out.println(name + " 完成执行。");
}
private void work() {
try {
Thread.sleep(5000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
输出结果t1 acquiring lock on java.lang.Object@917d8d4
t1 acquired lock on java.lang.Object@917d8d4
t2 acquiring lock on java.lang.Object@5c4b42fb
t2 acquired lock on java.lang.Object@5c4b42fb
t1 released lock on java.lang.Object@917d8d4
t1 acquiring lock on java.lang.Object@5c4b42fb
t1 acquired lock on java.lang.Object@5c4b42fb
t2 released lock on java.lang.Object@5c4b42fb
t2 acquiring lock on java.lang.Object@528cb702
t2 acquired lock on java.lang.Object@528cb702
t1 released lock on java.lang.Object@5c4b42fb
t2 released lock on java.lang.Object@528cb702
t1 完成执行。
t2 完成执行。