// 包声明 - 将相关的类组织在一起
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");


    }
}