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

今日项目之线程同步操作项目

目录

要求

这该如何是好

代码实现

项目结构

代码

BankAccount.java

WithdrawTask.java

Main.java

执行结果

关键点

关键点解释


要求

使用线程同步实现两个用户同时安全操作一个银行账户
张三准备取款
张三完成取款
张三的妻子准备取款
张三的妻子完成取款
张三准备取款
张三完成取款
张三的妻子准备取款
张三的妻子完成取款
张三准备取款
张三完成取款
余额不足以支付张三的妻子的取款,余额为C
余额不足以支付张三的取款,余额为0
余额不足以支付张三的妻子的取款,余额为0
余额不足以支付张三的取款,余额为0
余额不足以支付张三的妻子的取款,余额为0
 

这该如何是好

思路说明
线程同步 使用synchronized关键字确保账户操作的原子性
竞态条件解决多线程同时访问共享资源导致的数据不一致问题
线程安全 通过同步方法保证账户状态的一致性
阻塞机制 synchronized实现的隐式锁机制
共享资源 BankAccount作为多个线程共享的临界资源
线程通信通过控制台输出展示线程执行顺序

代码实现

项目结构

BankAccountSync/
├── src/
├── BankAccount.java       # 银行账户类
├── WithdrawTask.java      # 取款任务类
└── Main.java              # 主程序

代码

BankAccount.java
public class BankAccount {private int balance;private final String accountName;public BankAccount(String accountName, int initialBalance) {this.accountName = accountName;this.balance = initialBalance;}// 同步取款方法public synchronized void withdraw(String userName, int amount) {System.out.println(userName + "准备取款");try {// 模拟实际业务处理延迟Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}if (balance >= amount) {balance -= amount;System.out.println(userName + "完成取款");} else {System.out.println("余额不足以支付" + userName + "的取款,余额为" + balance);}}public int getBalance() {return balance;}
}
WithdrawTask.java
public class WithdrawTask implements Runnable {private final BankAccount account;private final String userName;private final int amount;public WithdrawTask(BankAccount account, String userName, int amount) {this.account = account;this.userName = userName;this.amount = amount;}@Overridepublic void run() {account.withdraw(userName, amount);}
}
Main.java
public class Main {public static void main(String[] args) {// 创建初始余额为3000的账户BankAccount account = new BankAccount("家庭账户", 3000);// 创建取款任务线程Thread zhangsanThread1 = new Thread(new WithdrawTask(account, "张三", 1000));Thread wifeThread1 = new Thread(new WithdrawTask(account, "张三的妻子", 1000));Thread zhangsanThread2 = new Thread(new WithdrawTask(account, "张三", 1000));Thread wifeThread2 = new Thread(new WithdrawTask(account, "张三的妻子", 1000));Thread zhangsanThread3 = new Thread(new WithdrawTask(account, "张三", 1000));Thread wifeThread3 = new Thread(new WithdrawTask(account, "张三的妻子", 1000));// 按题目要求的顺序启动线程zhangsanThread1.start();try { Thread.sleep(50); } catch (InterruptedException e) {} // 确保启动顺序wifeThread1.start();try { Thread.sleep(50); } catch (InterruptedException e) {}zhangsanThread2.start();try { Thread.sleep(50); } catch (InterruptedException e) {}wifeThread2.start();try { Thread.sleep(50); } catch (InterruptedException e) {}zhangsanThread3.start();try { Thread.sleep(50); } catch (InterruptedException e) {}wifeThread3.start();// 等待所有线程完成try {zhangsanThread1.join();wifeThread1.join();zhangsanThread2.join();wifeThread2.join();zhangsanThread3.join();wifeThread3.join();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

执行结果

关键点

关键点解释
  1. 线程同步机制

    • 使用synchronized修饰withdraw方法,确保同一时间只有一个线程能执行取款操作

    • 防止多个线程同时修改余额导致的数据不一致

  2. 余额控制逻辑

    • 每次取款前检查余额是否充足

    • 余额不足时输出警告信息而不修改余额

    • 初始余额3000元,每次取款1000元

  3. 线程启动顺序

    • 使用Thread.sleep(50)确保线程按题目要求的顺序启动

    • 实际业务中通常不需要控制启动顺序,此处仅为满足题目输出要求

  4. 余额变化过程

    • 前三次取款成功(3000→2000→1000→0)

    • 后续取款因余额不足失败

http://www.dtcms.com/a/325678.html

相关文章:

  • 生成模型实战 | MuseGAN详解与实现
  • encoder-only / decoder-only / encoder-decoder架构分析
  • 云原生应用的DevOps2(Jenkins渗透场景)
  • Spring Boot 单元测试:@SpyBean 使用教程
  • Linux生成自签名 SSL 证书(适用于测试或内部使用)
  • CI/CD渗透测试靶场
  • cesium/resium 修改子模型材质
  • [Oracle] UNPIVOT 列转行
  • MySQL 数据操作全流程:创建、读取、更新与删除实战
  • openEuler、 CentOS、Ubuntu等 Linux 系统中,Docker 常用命令总结
  • FPGA+护理:跨学科发展的探索(一)
  • SAE J2716多协议网关的硬件架构与实时协议转换机制解析
  • 三种常见的菜单路由封装方式详解
  • rust编译过程的中间表现形式如何查看,ast,hir,mir
  • Rust学习笔记(一)|Rust初体验 猜数游戏
  • Excel 实战:基因表达矩阵前处理中测序符号的快速剥离方法
  • K210人脸识别系统
  • 在Linux中部署tomcat
  • 【Redis的安装与配置】
  • 如何理解Tomcat、Servlet、Catanalina的关系
  • 从零开始的云计算生活——第四十一天,勇攀高峰,Kubernetes模块之单Master集群部署
  • 微美全息(NASDAQ:WIMI)Raft携手节点动态评估:引领联盟链高性能共识新潮流
  • 为 Promethus 配置https访问
  • 机器学习 - Kaggle项目实践(1)Titanic
  • 揭开内容分发网络(CDN)的神秘面纱:互联网的隐形加速器
  • 飞翔的小鸟
  • 【数据结构入门】二叉树(1)
  • day23|前端学习三件套
  • 了解不同电磁仿真类型中的电容报告
  • 数学建模——灰色预测(GM11)