如何在 Java 中避免死锁?
在 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 + " finished execution."); } private void work() { try { Thread.sleep(5000); } catch (InterruptedException ie) { ie.printStackTrace(); } } }
输出
t1 acquiring lock on java.lang.Object@27a54c50 t1 acquired lock on java.lang.Object@27a54c50 t2 acquiring lock on java.lang.Object@2ee6a5aa t2 acquired lock on java.lang.Object@2ee6a5aa t1 released lock on java.lang.Object@27a54c50 t1 acquiring lock on java.lang.Object@2ee6a5aa t2 released lock on java.lang.Object@2ee6a5aa t2 acquiring lock on java.lang.Object@20214e06 t1 acquired lock on java.lang.Object@2ee6a5aa t2 acquired lock on java.lang.Object@20214e06 t1 released lock on java.lang.Object@2ee6a5aa t2 released lock on java.lang.Object@20214e06 t1 finished execution. t2 finished execution.
广告