Java多线程并发问题:锁竞争和死锁示例
在Java多线程编程中,锁竞争(Race Condition)和死锁是常见的并发问题。
锁竞争示例:
```java
// 创建两个线程A和B
class MyRunnable implements Runnable {
private Object lock = new Object();// 这个方法将会被线程调用
@Override
public void run() {try {
synchronized (lock) { // 使用同一个锁
System.out.println("Thread " + Thread.currentThread().getName() + " is executing the critical section.");
lock.wait(); // 等待锁释放
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
MyRunnable threadA = new MyRunnable();
MyRunnable threadB = new MyRunnable();
// 创建并启动两个线程
Thread threadA1 = new Thread(threadA);
Thread threadB1 = new Thread(threadB);
threadA1.start(); // 启动线程A
threadB1.start(); // 启动线程B
// 此时,锁竞争的问题可能会出现
// 如果两个线程同时执行到synchronized (lock) {代码块}
// 并且都试图获取同一个锁(lock),
// 那么就可能会导致锁竞争问题。
}
}
2. 死锁示例:
```java
// 创建两个互斥资源,比如两个房间
class Room {
private Object lock = new Object();
// 获取房间的方法,需要获取锁才能进入
public synchronized void enter() {
System.out.println("Thread " + Thread.currentThread().getName() + " entered the room.");
lock.notify(); // 取消对房间的锁定,让其他线程有机会进入
}
}
public class Main {
public static void main(String[] args) {
Room room1 = new Room();
Room room2 = new Room();
// 创建两个线程A和B,分别尝试获取房间并进入
Thread threadA1 = new Thread(() -> {
System.out.println("Thread " + Thread.currentThread().getName() + " started acquiring room 1.");
try {
room1.enter(); // 尝试获取房间并进入
System.out.println("Room 1 successfully entered by Thread " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
Thread threadB1 = new Thread(() -> {
System.out.println("Thread " + Thread.currentThread().getName() + " started acquiring room 2.");
try {
room2.enter(); // 尝试获取房间并进入
System.out.println("Room 2 successfully entered by Thread " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
// 启动线程A和B
threadA1.start();
threadB1.start();
try {
// 主线程会等待所有子线程结束后再退出
System.out.println("Main thread is waiting for all subthreads to finish.");
Thread.sleep(5000); // 等待5秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上述示例中,两个线程(A和B)分别试图获取两个房间(room1和room2)。由于这两个资源是互斥的,所以每个线程都需要获取并释放锁(lock)才能进入房间。
如果线程A先获得room1的锁,并尝试获取room2的锁。同时,线程B也获得了room2的锁,并尝试获取room1的锁。这样就形成了死锁:两个线程都等待对方释放资源,导致都无法继续执行。
还没有评论,来说两句吧...