当前位置: 首页 > article >正文

第七十三篇 从电影院售票到停车场计数:生活场景解析Java原子类精髓

目录

    • 一、原子类基础:电影院售票系统
      • 1.1 传统售票的并发问题
      • 1.2 原子类解决方案
    • 二、原子类家族:超市收银系统
      • 2.1 基础类型原子类
      • 2.2 数组类型原子类
    • 三、CAS机制深度解析:停车场管理系统
      • 3.1 CAS工作原理
      • 3.2 车位计数器实现
    • 四、高性能实践:银行账户系统
      • 4.1 账户余额更新
      • 4.2 性能对比测试
    • 五、原子类进阶:电影院选座系统
      • 5.1 座位状态管理
      • 5.2 批量更新优化

想象电影院售票处:多个窗口同时售票却不会售出重复座位;停车场入口自动计数系统实时更新车位状态——这正是Java原子类的完美生活映射。本文将用日常场景揭秘高并发环境下的无锁编程奥秘。

一、原子类基础:电影院售票系统

1.1 传统售票的并发问题

// 非原子操作导致超卖
public class TicketCounter {private int totalTickets = 100;public void sellTicket() {if(totalTickets > 0) {// 此处可能被其他线程中断totalTickets--; System.out.println("售出1张票,剩余:" + totalTickets);}}
}

1.2 原子类解决方案

public class AtomicTicketCounter {private final AtomicInteger tickets = new AtomicInteger(100);public void safeSellTicket() {int current;do {current = tickets.get();if(current <= 0) {System.out.println("票已售罄");return;}} while(!tickets.compareAndSet(current, current - 1));System.out.println("安全售出,剩余:" + tickets.get());}
}

二、原子类家族:超市收银系统

2.1 基础类型原子类

// 收银台计数器
AtomicLong dailySales = new AtomicLong(0); // 每笔交易更新
void processTransaction(double amount) {// 累加销售额dailySales.addAndGet((long)(amount * 100));// 更新最高单笔交易AtomicReference<Double> maxTransaction = new AtomicReference<>(0.0);maxTransaction.accumulateAndGet(amount, Math::max);
}

2.2 数组类型原子类

// 货架商品库存
AtomicIntegerArray shelfStock = new AtomicIntegerArray(10); // 补充第3号货架商品
void restockShelf(int shelfId, int quantity) {shelfStock.addAndGet(shelfId, quantity);
}// 顾客购买商品
boolean purchaseItem(int shelfId) {int current;do {current = shelfStock.get(shelfId);if(current <= 0) return false;} while(!shelfStock.compareAndSet(shelfId, current, current-1));return true;
}

三、CAS机制深度解析:停车场管理系统

3.1 CAS工作原理

读取当前值
计算新值
当前值是否未变?
更新成功
重试操作

3.2 车位计数器实现

public class ParkingLot {private final AtomicInteger availableSpots;private final int totalSpots;public ParkingLot(int capacity) {this.totalSpots = capacity;this.availableSpots = new AtomicInteger(capacity);}// 车辆进入public boolean carEnter() {int current;do {current = availableSpots.get();if(current <= 0) return false;} while(!availableSpots.compareAndSet(current, current - 1));updateDisplay();return true;}// 车辆离开public void carExit() {availableSpots.incrementAndGet();updateDisplay();}private void updateDisplay() {System.out.println("当前车位: " + availableSpots + "/" + totalSpots);}
}

四、高性能实践:银行账户系统

4.1 账户余额更新

public class BankAccount {private final AtomicLong balance;public BankAccount(long initial) {this.balance = new AtomicLong(initial);}// 无锁存款public void deposit(long amount) {balance.addAndGet(amount);}// 安全取款(避免透支)public boolean withdraw(long amount) {long current;do {current = balance.get();if(current < amount) return false;} while(!balance.compareAndSet(current, current - amount));return true;}// 转账操作public boolean transferTo(BankAccount target, long amount) {if(this.withdraw(amount)) {target.deposit(amount);return true;}return false;}
}

4.2 性能对比测试

操作方式100万次操作耗时适用场景
synchronized450ms复杂事务处理
ReentrantLock380ms需要高级功能的场景
AtomicLong120ms简单计数器场景

五、原子类进阶:电影院选座系统

5.1 座位状态管理

public class SeatManager {// 使用AtomicReference数组管理座位状态private final AtomicReference<SeatStatus>[] seats;public SeatManager(int capacity) {seats = new AtomicReference[capacity];// 初始化所有座位为空闲Arrays.fill(seats, new AtomicReference<>(SeatStatus.AVAILABLE));}// 预订座位public boolean bookSeat(int seatId) {return seats[seatId].compareAndSet(SeatStatus.AVAILABLE, SeatStatus.OCCUPIED);}// 释放座位public void releaseSeat(int seatId) {seats[seatId].set(SeatStatus.AVAILABLE);}enum SeatStatus { AVAILABLE, OCCUPIED }
}

5.2 批量更新优化

// 使用LongAdder优化高频计数器
public class TicketCounter {private final LongAdder totalSales = new LongAdder();private final LongAdder vipSales = new LongAdder();public void sellTicket(boolean isVip) {totalSales.increment();if(isVip) vipSales.increment();}// 生成报表public void generateReport() {System.out.println("总售票: " + totalSales.sum());System.out.println("VIP票: " + vipSales.sum());}
}

🎯下期预告:《Java 并发容器》
💬互动话题:不深思则不能造于道。不深思而得者,其得易失
🏷️温馨提示:我是[随缘而动,随遇而安], 一个喜欢用生活案例讲技术的开发者。如果觉得有帮助,点赞关注不迷路🌟

http://www.lryc.cn/news/2405025.html

相关文章:

  • 【原创】基于视觉模型+FFmpeg+MoviePy实现短视频自动化二次编辑+多赛道
  • C++----剖析list
  • 纳米AI搜索与百度AI搜、豆包的核心差异解析
  • 不到 2 个月,OpenAI 火速用 Rust 重写 AI 编程工具。尤雨溪也觉得 Rust 香!
  • 人工智能:网络安全的“智能守护者”
  • Python60日基础学习打卡Day46
  • 综述论文解读:Editing Large Language Models: Problems, Methods, and Opportunities
  • WEB3全栈开发——面试专业技能点P1Node.js / Web3.js / Ethers.js
  • Vscode下Go语言环境配置
  • Java八股文——MySQL篇
  • Oracle数据库学习笔记 - 创建、备份和恢复
  • Go语言--语法基础5--基本数据类型--输入输出(1)
  • 永磁同步电机无速度算法--自适应龙贝格观测器
  • LangChain工具集成实战:构建智能问答系统完整指南
  • 【razor】x264 在 的intra-refresh和IDR插帧
  • 分库分表的取舍
  • 随机算法一文深度全解
  • 在 Conda 环境下配置 Jupyter Notebook 环境和工作目录
  • MS39531N 是一款正弦驱动的三相无感直流电机驱动器,具有最小振动和高效率的特点
  • web3-基于贝尔曼福特算法(Bellman-Ford )与 SMT 的 Web3 DeFi 套利策略研究
  • 分析 java 的 Map<String,Map<String, List<Map<String,Integer>>>>
  • ChatterBox - 轻巧快速的语音克隆与文本转语音模型,支持情感控制 支持50系显卡 一键整合包下载
  • 前端开发面试题总结-HTML篇
  • 嵌入式学习--江协stm32day4
  • 【Matlab】连接SQL Server 全过程
  • MS8551/MS8552/MS8554 单电源、轨到轨输入输出、高精度运放,可替代AD8551/AD8552/AD8554
  • 什么是 Ansible 主机和组变量
  • F#语言的区块链
  • 9.RV1126-OPENCV 视频的膨胀和腐蚀
  • 查找 Vue 项目中未使用的依赖