Java中的并发编程:锁竞争、死锁等问题实例
在Java中,并发编程涉及多个方面,包括锁竞争、死锁等。以下是一些实例:
锁竞争:
a. 代码示例:```java
// 假设我们有两个共享资源对象resourceA和resourceB
class Resource {
private Object obj;
private Lock lock;
// 构造器,初始化锁
Resource(Object obj, Lock lock) {
this.obj = obj;
this.lock = lock;
}
}
// 同步访问资源
void accessResource(Resource resourceA, Resource resourceB) {
resourceA.lock.lock();
try {
// 共享资源操作
System.out.println("Accessing resource A");
resourceB.lock.lock();
try {
// 再次共享资源操作
System.out.println("Accessing resource B");
} finally {
// 释放锁
resourceB.lock.unlock();
resourceA.lock.unlock();
}
} catch (Exception e) {
// 锁竞争异常处理
e.printStackTrace();
}
}
```
b. 现象:如果两个线程同时访问资源A和资源B,可能会因为锁的争抢而导致执行顺序混乱。
死锁:
a. 产生条件:- 循环等待:一个线程等待另一个线程释放已获得的锁。
- 不可进入状态:线程因等待资源而进入的一种阻塞状态,此时线程无法进行任何操作。
b. 示例:
```java
// 假设我们有四个共享资源对象
class Resource {
private Object obj;
private Lock lock;
// 构造器,初始化锁
Resource(Object obj, Lock lock) {
this.obj = obj;
this.lock = lock;
}
}
// 线程1 - 需要resourceA和resourceB
class Thread1 extends Thread {
private Resource resourceA, resourceB;
public Thread1(Resource resourceA, Resource resourceB) {
this.resourceA = resourceA;
this.resourceB = resourceB;
}
@Override
public void run() {
try {
// 获取资源锁
resourceA.lock.lock();
resourceB.lock.lock();
System.out.println("Thread1 started");
// 线程操作,这里假设是执行一些耗时的操作
Thread.sleep(2000); // 模拟耗时操作
// 共享资源释放
resourceB.unlock();
resourceA.unlock();
System.out.println("Thread1 finished");
} catch (InterruptedException | Exception e) {
e.printStackTrace();
} finally {
// 释放所有锁
resourceB.lock.unlock();
resourceA.lock.unlock();
}
}
}
// 线程2 - 需要resourceB和resourceC
class Thread2 extends Thread {
private Resource resourceB, resourceC;
public Thread2(Resource resourceB, Resource resourceC) {
this.resourceB = resourceB;
this.resourceC = resourceC;
}
@Override
public void run() {
try {
// 获取资源锁
resourceB.lock.lock();
resourceC.lock.lock();
System.out.println("Thread2 started");
// 线程操作,这里假设是执行一些耗时的操作
Thread.sleep(1500); // 模拟耗时操作
// 共享资源释放
resourceC.unlock();
resourceB.unlock();
System.out.println("Thread2 finished");
} catch (InterruptedException | Exception e) {
e.printStackTrace();
} finally {
// 释放所有锁
resourceC.lock.unlock();
resourceB.lock.unlock();
}
}
}
// 启动线程
Thread1 thread1 = new Thread1(resourceA, resourceB));
thread1.start();
Thread2 thread2 = new Thread2(resourceB, resourceC));
thread2.start();
// 程序结束,等待所有线程完成
while (thread1.isAlive() || thread2.isAlive()) {
try {
// 线程等待
Thread.sleep(100); // 模拟等待时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("All threads finished.");
}
}
```
在这个例子中,线程1和线程2需要共享资源A、B和C。如果两个线程同时访问这些资源,可能会导致死锁。注意这个例子是模拟的,实际编程时需要考虑线程安全和异常处理等问题。
还没有评论,来说两句吧...