Java并发编程中的死锁与竞态条件:原理、案例与解决方案
一、引言
在高并发系统中,多线程竞争共享资源是不可避免的挑战。Java并发编程中常见的问题包括竞态条件(Race Condition)、死锁(Deadlock)和资源竞争(Resource Contention)。这些问题可能导致数据不一致、程序挂起或性能下降。
本文通过实际案例分析,深入探讨这些问题的成因、表现形式及解决方案,帮助开发者构建更健壮的并发程序。
二、竞态条件与原子性问题
案例1:银行账户并发操作中的竞态条件
问题描述
多个线程同时修改共享变量(如银行账户余额),导致计算结果错误。
代码示例
public class BankAccount {private int balance;public void deposit(int amount) {balance += amount; // 非原子操作}public void withdraw(int amount) {balance -= amount; // 非原子操作}
}
问题分析
balance += amount
和balance -= amount
是读-修改-写操作,中间状态可能被覆盖。- 预期结果:
1000 + (10*100) - (20*50) = 1000
。 - 实际结果:可能为
999
、1001
或其他随机值。
解决方案
-
使用
synchronized
确保原子性:public synchronized void deposit(int amount) { ... } public synchronized void withdraw(int amount) { ... }
-
使用原子类(如
AtomicInteger
):import java.util.concurrent.atomic.AtomicInteger; private AtomicInteger balance; public void deposit