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

Java基础-红包雨游戏-多线程

目录

案例要求:

实现思路:

代码:

Employee

RedPacket

RedPacketRain

总结:


案例要求:

实现思路:

创建一个员工类,id和抢到的金额,创建一个红包类,里面就是金额,创建一个抽奖操作类,设置10个线程进行抢红包操作

代码:

Employee

import lombok.AllArgsConstructor;public class Employee {private final int id;private int totalAmount; // 抢到的总金额private final Object lock = new Object(); // 用于同步的锁对象public Employee(int id) {this.id = id;this.totalAmount = 0;}// 线程安全的添加金额方法public void addAmount(int amount) {synchronized (lock) {totalAmount += amount;}}public int getId() {return id;}public int getTotalAmount() {synchronized (lock) {return totalAmount;}}
}

RedPacket

public class RedPacket {private final int amount; // 红包金额public RedPacket(int amount) {this.amount = amount;}public int getAmount() {return amount;}
}

RedPacketRain

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;public class RedPacketRain {// 红包列表(使用线程安全的CopyOnWriteArrayList)private static final List<RedPacket> redPackets = new CopyOnWriteArrayList<>();// 员工列表private static final List<Employee> employees = new ArrayList<>();public static void main(String[] args) throws InterruptedException {// 1. 初始化红包(200个)generateRedPackets();// 2. 初始化员工(100个)for (int i = 1; i <= 100; i++) {employees.add(new Employee(i));}// 3. 创建多个线程模拟抢红包int threadCount = 10; // 10个抢红包线程Thread[] threads = new Thread[threadCount];for (int i = 0; i < threadCount; i++) {threads[i] = new Thread(new GrabRedPacketTask(), "抢红包线程-" + (i + 1));}// 4. 启动所有线程long startTime = System.currentTimeMillis();for (Thread thread : threads) {thread.start();}// 5. 等待所有线程执行完毕for (Thread thread : threads) {thread.join();}long endTime = System.currentTimeMillis();System.out.println("\n===== 抢红包结束,耗时:" + (endTime - startTime) + "ms =====");// 6. 按总金额排序并展示结果employees.sort((e1, e2) -> Integer.compare(e2.getTotalAmount(), e1.getTotalAmount()));System.out.println("\n===== 抢红包结果(按金额降序) =====");for (Employee emp : employees) {System.out.println("员工" + emp.getId() + ":总金额 " + emp.getTotalAmount() + "元");}}// 生成红包(80%小红包1-30元,20%大红包31-100元)private static void generateRedPackets() {Random random = new Random();// 160个小红包for (int i = 0; i < 160; i++) {redPackets.add(new RedPacket(random.nextInt(30) + 1));}// 40个大红包for (int i = 0; i < 40; i++) {redPackets.add(new RedPacket(random.nextInt(70) + 31));}}// 抢红包任务static class GrabRedPacketTask implements Runnable {private final Random random = new Random();@Overridepublic void run() {// 循环抢红包,直到红包抢完while (!redPackets.isEmpty()) {// 随机获取一个红包(线程安全的移除)RedPacket packet = null;synchronized (redPackets) { // 保证红包列表操作的线程安全if (!redPackets.isEmpty()) {int index = random.nextInt(redPackets.size());packet = redPackets.remove(index);}}// 如果抢到红包,随机分配给一个员工if (packet != null) {int empIndex = random.nextInt(employees.size());Employee emp = employees.get(empIndex);emp.addAmount(packet.getAmount());// 打印抢红包信息(可选,过多会影响性能)// System.out.println(Thread.currentThread().getName() + ":员工" + emp.getId() + "抢到 " + packet.getAmount() + "元");}}}}
}

总结:

本文实现了一个多线程抢红包系统。系统包含三个核心类:Employee类(员工信息)、RedPacket类(红包金额)和RedPacketRain类(主程序)。通过10个线程模拟并发抢红包过程:初始化200个红包(80%为1-30元,20%为31-100元)和100个员工,使用CopyOnWriteArrayList保证线程安全,随机分配红包给员工。最终按员工抢到的总金额降序输出结果。关键点包括:使用同步锁保证金额累加安全,随机红包分配策略,以及线程间的并发控制。

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

相关文章:

  • 如何判断一个数是 2 的幂 / 3 的幂 / 4 的幂 / n 的幂 位运算 总结和思考 每日一题 C++的题解与思路
  • 後端開發技術教學(四) 數據交互延伸
  • Visual Studio Code (v1.103) 中 GitHub Copilot 最新更新!
  • Microsoft Office Visio(流程图)学习笔记
  • 信息安全及防火墙总结
  • Android 开发问题:The specified child already has a parent.
  • 五十八、【Linux系统nginx服务】nginx代理服务器、nginx优化
  • MySQL 从入门到精通 2:函数
  • Linux的软件防火墙iptables
  • 香港服务器容器网络插件的多节点通信性能基准测试
  • LeetCode 刷题【36. 有效的数独】
  • 6- Python 网络爬虫—验证码突破全解析: 从 OCR 到深度学习的对抗实战指南
  • CSS 选择器进阶:用更聪明的方式定位元素
  • DBSCAN聚类算法实战全解析
  • 多Agent技术发展与进化
  • vue+flask山西非遗文化遗产图谱可视化系统
  • IntelliJ IDEA 新手全方位使用指南
  • 深入 FastMCP 源码:认识 tool()、resource() 和 prompt() 装饰器
  • Kubelet 探针如何选择 IP:status.PodIP 溯源与“同 Pod 两个 IP“现象解析
  • 回答“http协议 ,js组件化,工程化, seo优化策略 ,针对不同平台终端适配 web标注和兼容性”
  • nrm工具管理镜像源
  • 通过 Certimate 统一管理 SSL 证书 支持自动化申请、全平台部署
  • 第八章 SQL编程系列-Oracle慢SQL优化实战:从执行计划到索引设计的深度解析
  • 编程速递:2025 年巴西 Embarcadero 会议,期待您的到来
  • 金融通用智能体(Financial General Agent, FGA)的端到端解决方案
  • 视图是什么?有什么用?什么时候用?MySQL中的视图
  • Swift 实战:秒算两个数组的交集(LeetCode 349)
  • 一周学会Matplotlib3 Python 数据可视化-标注 (Annotations)
  • 力扣-74.搜索二维矩阵
  • [Oracle] MAX()和MIN()函数