Java多线程编程:常见死锁案例分析
Java多线程编程中,死锁是指两个或多个线程在执行过程中,因争夺资源而造成的一种僵局,使得这些线程无法继续执行下去。死锁发生时,线程会陷入无限等待状态,导致程序无法正常运行。以下是一些常见的死锁案例分析:
1.资源分配不当案例描述:
两个线程分别需要两个资源,但它们各自只获得了一个资源,然后都在等待对方释放资源。
代码示例:
```javapublic class DeadlockExample {
private static final Object resource1 = new Object();
private static final Object resource2 = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (resource1) {
System.out.println(“Thread1: Locked resource1”);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println(“Thread1: Locked resource2”);
}
}
});
Thread t2 = new Thread(() -> {
synchronized (resource2) {
System.out.println(“Thread2: Locked resource2”);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println(“Thread2: Locked resource1”);
}
}
});
t1.start();
t2.start();
}
}
```###2.嵌套锁案例描述:
一个线程在持有一个锁的同时尝试获取另一个锁,而另一个线程也持有另一个锁并尝试获取第一个锁。
代码示例:
```javapublic class NestedLocks {
private final Object outerLock = new Object();
private final Object innerLock = new Object();
public void method1() {
synchronized (outerLock) {
System.out.println(“Lock acquired on outerLock”);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (innerLock) {
System.out.println(“Lock acquired on innerLock”);
}
}
}
public void method2() {
synchronized (innerLock) {
System.out.println(“Lock acquired on innerLock”);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (outerLock) {
System.out.println(“Lock acquired on outerLock”);
}
}
}
}
```###3.线程顺序不一致案例描述:
多个线程按照不同的顺序请求相同的一组资源。
代码示例:
```javapublic class OrderDeadlock {
private static final Object lockA = new Object();
private static final Object lockB = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lockA) {
System.out.println(“Thread1: Locked A”);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB) {
System.out.println(“Thread1: Locked B”);
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lockB) {
System.out.println(“Thread2: Locked B”);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockA) {
System.out.println(“Thread2: Locked A”);
}
}
});
t1.start();
t2.start();
}
}
```###解决方案1. 避免嵌套锁:尽量减少嵌套锁的使用,或者确保所有线程以相同的顺序获取锁。
- 使用锁超时:使用
tryLock()
方法尝试获取锁,并设置超时时间,避免无限等待。 - 使用并发工具类:使用
java.util.concurrent
包中的并发工具类,如ReentrantLock
、Semaphore
等,它们提供了更灵活的锁机制。 - 检测死锁:使用JVM工具(如jconsole、jstack)检测死锁,并分析线程的调用栈。
通过以上方法,可以有效地避免和解决Java多线程编程中的死锁问题。
还没有评论,来说两句吧...