Java多线程:死锁、同步问题实例
死锁是多线程编程中的一个严重问题。当两个或更多的线程互相等待对方释放资源时,就会发生死锁。
以下是一个简单的Java多线程死锁示例:
// 线程1需要资源1和2
class Thread1 extends Thread {
private int resource1;
private int resource2;
public Thread1(int resource1, int resource2) {
this.resource1 = resource1;
this.resource2 = resource2;
}
@Override
public void run() {
synchronized (resource1) { // 资源1先被锁住
synchronized (resource2) { // 资源2再被锁住
System.out.println("Thread 1 acquired resources: " + resource1 + ", " + resource2);
if (releaseResources()) { // 如果能够释放资源,就退出循环
return;
}
}
}
System.out.println("Thread 1 could not release resources and is waiting.");
}
private boolean releaseResources() {
// 假设这里有一个可以用来测试是否能释放资源的方法
// 这个方法可能会抛出异常,所以我们需要捕获这些异常
if (releaseResource1() && releaseResource2()) {
return true;
} else {
System.out.println("Failed to release resources.");
return false;
}
}
private boolean releaseResource1() {
// 假设这里有一个释放资源1的方法
// 这个方法可能会抛出异常,所以我们需要捕获这些异常
if (resource1 > 0) {
resource1--;
System.out.println("Thread 1 released resource 1.");
return true;
} else {
System.out.println("Failed to release resource 1. Resource is already released.");
return false;
}
}
private boolean releaseResource2() {
// 类似于releaseResource1的方法
if (resource2 > 0) {
resource2--;
System.out.println("Thread 1 released resource 2.");
return true;
} else {
System.out.println("Failed to release resource 2. Resource is already released.");
return false;
}
}
}
// 线程2需要资源2和3
class Thread2 extends Thread {
private int resource2;
private int resource3;
public Thread2(int resource2, int resource3) {
this.resource2 = resource2;
this.resource3 = resource3;
}
@Override
public void run() {
synchronized (resource2) { // 资源2先被锁住
synchronized (resource3) { // 资源3再被锁住
System.out.println("Thread 2 acquired resources: " + resource2 + ", " + resource3);
if (releaseResources()) { // 如果能够释放资源,就退出循环
return;
}
}
}
System.out.println("Thread 2 could not release resources and is waiting.");
}
private boolean releaseResources() {
// 假设这里有一个可以用来测试是否能释放资源的方法
// 这个方法可能会抛出异常,所以我们需要捕获这些异常
if (resource2 > 0) {
resource2--;
System.out.println("Thread 2 released resource 2.");
return true;
} else {
System.out.println("Failed to release resource 2. Resource is already released.");
return false;
}
}
private boolean releaseResource3() {
// 类似于releaseResource2的方法
if (resource3 > 0) {
resource3--;
System.out.println("Thread 2 released resource 3.");
return true;
} else {
System.out.println("Failed to release resource 3. Resource is already released.");
return false;
}
}
}
public class DeadLockExample {
public static void main(String[] args) {
Thread1 thread1 = new Thread1(1, 2);
Thread2 thread2 = new Thread2(2, 3);
// 启动线程
thread1.start();
thread2.start();
// 等待所有线程执行完毕
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在这个例子中,线程1需要资源1和2,线程2需要资源2和3。当线程2先获得资源2后,它会尝试获取资源3。同时,线程1也会尝试获取资源1和2。由于两个线程都锁住了各自需要的资源,从而引发了死锁。
要解决这个问题,通常需要在设计系统时避免这种情况的发生,例如可以设定一个资源获取顺序或者使用信号量机制来控制并发访问资源的数量。
还没有评论,来说两句吧...