一、死锁问题
1. 死锁的定义
死锁是指两个或多个线程相互持有对方所需的资源,且彼此都不释放已持有的资源,导致所有线程永久阻塞的状态。
2. 死锁产生的必要条件
- 互斥条件:资源只能被一个线程持有(不可共享)。
- 持有并等待:线程持有部分资源,同时等待其他资源。
- 不可剥夺:资源不能被强制剥夺,只能由持有线程主动释放。
- 循环等待:线程间形成环形等待链(T1 等待 T2 的资源,T2 等待 T1 的资源)。
3. 死锁示例(Java 代码)
java
运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class DeadlockExample { private static final Object resource1 = new Object(); private static final Object resource2 = new Object();
public static void main(String[] args) { Thread thread1 = new Thread(() -> { synchronized (resource1) { System.out.println("Thread1 持有 resource1,尝试获取 resource2"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource2) { System.out.println("Thread1 同时持有 resource1 和 resource2"); } } });
Thread thread2 = new Thread(() -> { synchronized (resource2) { System.out.println("Thread2 持有 resource2,尝试获取 resource1"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource1) { System.out.println("Thread2 同时持有 resource1 和 resource2"); } } });
thread1.start(); thread2.start(); } }
|
4. 死锁的解决方法
- 破坏循环等待:统一资源获取顺序(如按资源 ID 从小到大获取)。
- 破坏持有并等待:一次性获取所有所需资源。
- **使用 tryLock ()**:尝试获取资源时设置超时,超时后释放已持有的资源。
老师样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class test05 { public static void main(String[] args) { DeadThread r1 = new DeadThread(); DeadThread r2 = new DeadThread();
Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start();
r1.flag = false; } }
class DeadThread implements Runnable { boolean flag = true; static Object o1 = new Object(); static Object o2 = new Object();
@Override public void run() { String name = Thread.currentThread().getName();
while (true) { if (flag == true) { synchronized (o1) { System.out.println(name + " 这是if中的语句 锁是o1"); synchronized (o2) { System.out.println(name + " 这是if中的语句 锁是o2"); } } } else { synchronized (o2) { System.out.println(name + " 这是else语句 锁是o2"); synchronized (o1) { System.out.println(name + " 这是else语句 锁是o1"); } } } } } }
|