Java多线程同步问题探讨:死锁示例
死锁在多线程编程中是一种常见的问题,如果设计不当,多个线程可能会因为互相等待对方释放资源而陷入无法继续执行的境地。
下面是一个简单的Java多线程死锁示例:
// 线程1,想要获取资源A
class Thread1 implements Runnable {
private int resourceA;
public Thread1(int resourceA) {
this.resourceA = resourceA;
}
@Override
public void run() {
try {
// 获取资源A后,会尝试获取资源B
synchronized (resourceA) { // 这里使用了Java的synchronized关键字
if (resourceB != null && !resourceB.isFree()) { // 如果资源B已经被其他线程占用
System.out.println("Thread1 waiting for resource B to be free...");
resourceA.wait(); // 等待资源A释放锁,让出执行权
} else {
System.out.println("Thread1 acquiring resource A...");
resourceA.acquire(); // 获取锁
if (resourceB != null && !resourceB.isFree()) { // 如果资源B已经被其他线程占用
System.out.println("Thread1 waiting for resource B to be free...");
resourceB.wait(); // 等待资源B释放锁,让出执行权
} else {
System.out.println("Thread1 acquiring resource B...");
resourceB.acquire(); // 获取锁
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 线程2,想要获取资源B
class Thread2 implements Runnable {
private int resourceB;
public Thread2(int resourceB) {
this.resourceB = resourceB;
}
@Override
public void run() {
try {
// 获取资源B后,会尝试获取资源A
synchronized (resourceB) { // 这里使用了Java的synchronized关键字
if (resourceA != null && !resourceA.isFree()) { // 如果资源A已经被其他线程占用
System.out.println("Thread2 waiting for resource A to be free...");
resourceA.wait(); // 等待资源A释放锁,让出执行权
} else {
System.out.println("Thread2 acquiring resource B...");
resourceB.acquire(); // 获取锁
if (resourceA != null && !resourceA.isFree()) { // 如果资源A已经被其他线程占用
System.out.println("Thread2 waiting for resource A to be free...");
resourceA.wait(); // 等待资源A释放锁,让出执行权
} else {
System.out.println("Thread2 acquiring resource A...");
resourceA.acquire(); // 获取锁
if (resourceB != null && !resourceB.isFree()) { // 如果资源B已经被其他线程占用
System.out.println("Thread2 waiting for resource B to be free...");
resourceB.wait(); // 等待资源B释放锁,让出执行权
} else {
System.out.println("Thread2 acquiring resource B...");
resourceB.acquire(); // 获取锁
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 主程序启动两个线程并等待其结束
public static void main(String[] args) {
Thread1 thread1 = new Thread1(0); // 创建一个资源A值为0的Thread1实例
Thread2 thread2 = new Thread2(1); // 创建一个资源B值为1的Thread2实例
thread1.start(); // 启动线程1
thread2.start(); // 启动线程2
try {
thread1.join(); // 等待线程1结束
thread2.join(); // 等待线程2结束
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Both threads have completed and resources are released."); // 打印消息,表示两个线程已经完成并释放了资源
}
在这个示例中,两个线程Thread1
和Thread2
分别尝试获取两个资源resourceA
和resourceB
。由于互斥的性质,一个资源在被任何线程占用时,其他线程必须等待其释放。
当Thread1
获得resourceA
后,它会等待resourceB
释放锁;而Thread2
的情况类似,它会等待resourceA
释放锁。
最终,如果所有资源都被正确地顺序获取和释放,那么死锁就不会发生。在上述示例中,如果没有意外,程序应该能够正常运行并完成任务。
还没有评论,来说两句吧...