实例解析:Java多线程并发中的锁问题
在Java的多线程编程中,锁(Lock)问题是非常常见且重要的。以下是关于锁问题的一些实例解析:
独占锁(Synchronized):
示例:有一个银行账户对象,多个线程可能尝试增加或减少账户金额。
class BankAccount {
private double balance = 0;
synchronized void deposit(double amount) {
balance += amount;
notifyAll(); // 当余额改变后通知所有等待的线程
}
synchronized void withdraw(double amount) {
if (amount > balance) {
System.out.println("Insufficient balance");
return;
}
balance -= amount;
notifyAll();
}
}
共享锁(ReentrantLock):
- 示例:多个线程可能需要同时访问和修改一个对象的某些属性。
```java
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class SharedResource {
private int count = 0;
Lock lock = new ReentrantLock();
public synchronized void increment() {
count++;
lock.unlock(); // 执行完操作后解锁,其他线程可以进入
lock.acquire(); // 获得锁后,再次锁定资源,防止其他线程修改
System.out.println("Incremented count: " + count);
}
public synchronized void decrement() {
if (count > 0) {
count--;
lock.unlock();
lock.acquire();
System.out.println("Decremented count: " + count);
} else {
System.out.println("Can't decrement count, it's already 0");
}
}
}
```- 示例:多个线程可能需要同时访问和修改一个对象的某些属性。
死锁(Deadlock):
示例:两个线程A和B,A持有资源1,B持有资源2,但它们都无法完成操作。
class DeadlockThread {
private Resource resource1 = new Resource(1);
private Resource resource2 = new Resource(2);
public void acquireResource1() {
synchronized (resource1) {
if (!resource1.isAvailable()) {
System.out.println("Can't acquire resource 1, it's already taken");
return;
}
resource1.use();
System.out.println("Acquired resource 1");
notifyAll(); // 通知等待的线程资源可用
}
}
public void acquireResource2() {
synchronized (resource2) {
if (!resource2.isAvailable())) {
System.out.println("Can't acquire resource 2, it's already taken");
return;
}
resource2.use();
System.out.println("Acquired resource 2");
notifyAll(); // 通知等待的线程资源可用
}
}
public void run() {
try {
acquireResource1();
acquireResource2();
System.out.println("Both resources acquired, executing operation...");
Thread.sleep(3000); // 模拟耗时操作
System.out.println("Operation completed.");
} catch (InterruptedException e) {
System.out.println("Interrupted during resource acquisition or execution");
e.printStackTrace();
}
finally {
System.out.println("资源释放完毕,线程退出...");
}
}
}
在上述例子中,A和B两个线程分别持有资源1和2,并且它们都无法完成自己的操作(即没有互斥)。这就导致了死锁的发生。
还没有评论,来说两句吧...