Java多线程实现简单抢红包

本文介绍了一个简单的抢红包程序实现,该程序使用Java语言,并通过线程安全机制来确保并发环境下的红包分配正确无误。文章详细展示了红包类、用户线程类及主类的设计思路,实现了多线程同时访问共享资源的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 抢红包是在并发场景下操纵和获取资源,只需要将操作和获取的过程建立线程安全机制即可;
  • 抢红包需要多线程同时访问同一共享资源,所以将共享资源作为成员变量注入线程类中供其调用 (使用操纵内存的方式);

实现过程

红包类:

// 红包实体,共享变量,通过直接操作内存实现
public class RedPack{
   
    // 红包剩余数量
    int remain;
    // 总金额
    double total;
	
    public RedPack (int remain, double total) {
        this.remain = remain;
        // 保留两位小数
        this.total = new BigDecimal(total).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

	// 抢红包的动作,加上了synchronized进行并发控制
    synchronized public double grab() {
        // 抢到的结果返回给线程展示
        double result;
        // 场景 1:还剩最后一个红包,直接拿走
        if (remain == 1) {
            result = new BigDecimal(total).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            total = 0;
            remain--;
        // 场景 2:超过一个红包,生成一个(0, total)之间的随机金额
        } else if (remain > 1) {
            result = new BigDecimal((Math.random()*total)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            total -= result;
            remain--;
        // 场景 3:红包被抢完了
        } else {
            result = 0;
        }
        return result;
    }
}

线程:用户类

public class User implements Runnable{

	// 用户编号,区分线程
    int num;
    // 引入共享变量
    RedPack rp;
    // 抢到的金额
    double money;

    public User (int num, RedPack rp) {
        this.num = num;
        this.rp = rp;
    }

    @Override
    public void run() {
        System.out.println("用户" + num + "尝试抢红包");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 抢红包
        money = rp.grab();
        if (money > 0) {
            System.out.println("用户" + num + "抢到" + money + "元");
        } else {
            System.out.println("用户" + num + "未能抢到红包");
        }
    }
}

主类:

public class Main {
	// 抢红包用户数
    static final int user = 5;
    // 红包个数
    static final int remain = 4;
    // 总金额
    static final double total = 10;

    public static void main(String[] args) {
        RedPack rp = new RedPack(remain, total);
        System.out.println("抢红包开始,当前红包剩余" + total + "元");
        // 启动用户数量的线程
        for (int k = 1; k <= user; k++) {
            new Thread(new User(k, rp)).start();
        }
    }
}

运行结果:

	抢红包开始,当前红包剩余10.0元
	用户1尝试抢红包
	用户3尝试抢红包
	用户2尝试抢红包
	用户5尝试抢红包
	用户4尝试抢红包
	用户3未能抢到红包
	用户1抢到0.52元
	用户4抢到6.99元
	用户2抢到0.5元
	用户5抢到1.99元
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值