

// 包声明 - 将相关的类组织在一起
package cn.meowrain;
// 引入 AtomicInteger 类,用于支持线程安全的原子操作
import java.util.concurrent.atomic.AtomicInteger;
// 主类,用于演示不同账户实现的功能
public class UseAccount {
public static void main(String[] args) {
// 创建一个非线程安全的账户,初始余额为 10000
Account unsafeAccount = new UnsafeAccount(10000);
Account.demo(unsafeAccount); // 测试非线程安全账户的行为
// 创建一个使用 synchronized 的线程安全账户,初始余额为 10000
Account safeAccountUseSync = new SafeAccount(10000);
Account.demo(safeAccountUseSync); // 测试 synchronized 账户的线程安全性
// 创建一个使用 AtomicInteger 的线程安全账户,初始余额为 10000
Account safeAccountWithAtomicInteger = new SafeAccountUseAtomicInteger(10000);
Account.demo(safeAccountWithAtomicInteger); // 测试使用原子操作的账户的线程安全性
}
}
// Account 接口,定义账户的基本操作规范
interface Account {
// 从账户中提取指定金额
void withdraw(Integer amount);
// 获取当前账户余额
Integer getBalance();
// 静态方法,用于模拟多线程环境下的账户操作并检测行为
static void demo(Account account) {
// 创建一个任务:循环提取 10 单位金额
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
account.withdraw(10);
}
};
// 启动两个线程,执行以上提取任务
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
// 等待两个线程执行完成
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终余额,观察多线程环境下的账户行为
System.out.println("最终余额: " + account.getBalance());
}
}
// 非线程安全的账户实现
class UnsafeAccount implements Account {
private Integer balance; // 账户余额
// 构造函数,初始化账户余额
public UnsafeAccount(Integer balance) {
this.balance = balance;
}
@Override
public void withdraw(Integer amount) {
// 不使用同步,直接修改余额(会导致线程安全问题)
this.balance -= amount;
}
@Override
public Integer getBalance() {
return balance; // 返回当前余额
}
}
// 使用 synchronized 关键字的线程安全账户实现
class SafeAccount implements Account {
private Integer balance; // 账户余额
// 构造函数,初始化账户余额
public SafeAccount(Integer balance) {
this.balance = balance;
}
@Override
public synchronized Integer getBalance() {
return this.balance; // 使用 synchronized 确保线程安全的访问
}
@Override
public synchronized void withdraw(Integer amount) {
this.balance -= amount; // 使用 synchronized 保护关键操作,防止并发问题
}
}
// 使用 AtomicInteger 实现线程安全账户
class SafeAccountUseAtomicInteger implements Account {
private AtomicInteger balance; // 使用 AtomicInteger 确保线程安全
// 构造函数,初始化账户余额
public SafeAccountUseAtomicInteger(int balance) {
this.balance = new AtomicInteger(balance);
}
@Override
public void withdraw(Integer amount) {
// 使用 CAS (Compare-And-Swap) 的方式保证线程安全地扣减金额
while (true) {
int prev = balance.get(); // 获取当前余额
int next = prev - amount; // 计算扣款后的余额
// 尝试更新余额,只有当当前值等于预期值时才会成功
if (balance.compareAndSet(prev, next)) {
break; // 如果更新成功,退出循环
}
}
}
@Override
public Integer getBalance() {
return balance.get(); // 获取线程安全的余额
}
}
package cn.meowrain;
import java.util.ArrayList;
import java.util.List;
interface Account {
Integer getBalance();
void withdraw(Integer amount);
static void demo(Account account) {
List<Thread> ts = new ArrayList<>();
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
ts.add(new Thread(() -> {
account.withdraw(10);
}, "T" + i));
}
ts.forEach(Thread::start);
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.nanoTime();
System.out.println(account.getBalance() + " cost: " + (end - start) + "ms");
}
}