- 互斥条件(Mutual Exclusion):至少有一个资源被排它性地占用,即一次只能由一个线程使用。
- 请求与保持条件(Hold and Wait):线程至少持有一个资源,并且在等待其他资源的同时不释放已经持有的资源。
- 不可剥夺条件(No Preemption):资源只能在线程使用完之后由线程自己释放,其他线程无法强制剥夺。
- 循环等待条件(Circular Wait):存在一个线程的资源请求链,使得每个线程都在等待下一个线程所持有的资源。
下面是一个简单的死锁示例代码:
public class DeadlockExample { private static Object resource1 = new Object(); private static Object resource2 = new Object(); public static void main(String[] args) { Thread thread1 = new Thread(() -> { synchronized (resource1) { System.out.println("Thread 1: Holding resource 1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource2) { System.out.println("Thread 1: Holding resource 1 and resource 2"); } } }); Thread thread2 = new Thread(() -> { synchronized (resource2) { System.out.println("Thread 2: Holding resource 2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource1) { System.out.println("Thread 2: Holding resource 1 and resource 2"); } } }); thread1.start(); thread2.start(); } }
在上述代码中,两个线程分别尝试获取resource1和resource2这两个资源。由于互斥条件和请求与保持条件的存在,当线程1获取了resource1后,它还需要获取resource2才能继续执行,但此时resource2已经被线程2占用。同时,线程2也在等待获取resource1。因此,两个线程形成了循环等待条件,导致死锁的发生。
要解决死锁问题,可以采取以下策略:避免使用多个锁、按照固定的顺序获取锁、使用超时机制等。