理解并避免Java多线程同步问题示例
在Java多线程编程中,同步问题是非常常见的。以下是一些示例来帮助你理解和避免这些问题:
共享资源导致的竞态条件(Race Condition):
```java
class Counter {
int count = 0;synchronized void increment() {
count++;
}
synchronized int decrement() {
if (count > 0) {
count--;
}
return count;
}
}
public class RaceConditionExample {
Counter counter = new Counter();
// 竞态条件
new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
})).start();
// 同步调用,避免竞态条件
for (int i = 0; i < 10000; i++) {
counter.decrement();
try {
Thread.sleep(1); // 线程睡眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
RaceConditionExample example = new RaceConditionExample();
example.run();
}
}
在这个例子中,两个线程同时尝试增加计数器的值,导致了竞态条件。
2. **死锁(Deadlock)**:
```java
class Resource {
// 假设资源是互斥的
boolean available = true;
synchronized void acquire() {
if (available) {
available = false;
return;
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt(); // 线程中断,避免死循环
}
}
synchronized void release() {
available = true;
notifyAll(); // 唤醒等待的线程
}
}
public class DeadlockExample {
private Resource resource1 = new Resource();
private Resource resource2 = new Resource();
public void acquireResources() {
resource1.acquire(); // 资源1获得锁
resource2.acquire(); // 资源2获得锁
}
public void releaseResources() {
resource1.release(); // 资源1释放锁
resource2.release(); // 资源2释放锁
}
public static void main(String[] args) {
DeadlockExample example = new DeadlockExample();
example.acquireResources(); // 获取资源,形成死锁
example.releaseResources(); // 无法释放资源,导致死锁
}
}
在这个例子中,两个线程分别获取了资源1和资源2的锁。当一个线程完成操作后试图释放锁,但因为另一个线程持有资源1或资源2的锁,所以无法解锁并释放资源。这就形成了死锁。
为了避免这些同步问题,你可以使用Java并发工具类(如java.util.concurrent.locks.Lock
、ReentrantLock
等)来更精确地控制锁的获取和释放。
还没有评论,来说两句吧...