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保证线程安全,随机分配红包给员工。最终按员工抢到的总金额降序输出结果。关键点包括:使用同步锁保证金额累加安全,随机红包分配策略,以及线程间的并发控制。