疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java多线程实现抢红包


 

 
在准备写这个代码之前,我着实的复习和加深了对线程操作的使用,同步和数据共享!
说一下代码的思路:
首先抢红包,人、红包抽象为两个对象,人(获取到红包)红包(总额,数量,提供生成随机金额方法)
其中,生成随机红包有两种方案,第一种:获取的时候生成,第二种:先生成好所有的红包
对于两种方案都涉及到数据同步和共享,红包的总额就是一个共享数据,获取随机生成的红包金额方法需要加锁,保证生成随机金额时只有一个线程在操作。
坑的点: 1、如果钱数0.04,数量4个,类似这样的需要特殊处理
 2、为了生成钱数的概率达到尽可能的平等 val = new Random().nextInt(totalVal/count);
 3、便于金额的操作,换算为整形进行操作
 4、随机生成的金额可能是0,需要进行判断处理
以下就是代码,如果有哪里不对,请大佬指教!
[java] view plain copy
package com.ccq;  
  
import java.util.Random;  
  
public class FirstThread {  
    public static void main(String[] args) {  
        // 10个红包,5个人抢  
        Bao bao = new Bao(10, 5);  
        User user = new User(bao);  
        for(int i=0;i<10;i++) {  
            new Thread(user).start();  
        }  
    }  
}  
 
// 每一个用户都是一个线程  
class User implements Runnable{  
    private Bao bao;  
    public User(Bao bao) {  
        this.bao = bao;  
    }  
    @Override  
    public void run() {  
        double money = bao.getRandomMoney();  
        if(money == 0) {  
            System.out.println(Thread.currentThread().getName() + "不好意思,您手慢了!");  
        }else {  
            System.out.println(Thread.currentThread().getName() + "抢到 " + money + "元");  
        }  
          
    }  
}  
  
class Bao{  
    private double total; // 总钱数  
    private int totalVal; // 随机生成整数,将钱数化为整数  
    private int count;    // 红包总数  
  
    public Bao(double total, int count) {  
        this.total = total;  
        this.count = count;  
        this.totalVal = (int)(total * 100);  
    }  
      
    public synchronized double getRandomMoney() {  
        int val;  
        // 当前剩余钱数 0.04 4人  
        if(count !=0 && totalVal / count == 1) {  
            val = 1;  
            totalVal = totalVal - val;  
            count--;  
            return val/100.0;  
        }  
          
        if(count <= 0) {  
            val = 0;  
        }else if(count == 1) {  
            val = totalVal;  
        }else {  
            int temp; //剩下的金额  
            while(true) {  
                // 随机生成当前金额的随机数 [0,totalVal/count),尽量平均一点  
                val = new Random().nextInt(totalVal/count);  
                temp = totalVal - val;  
                // 判断生成的金额大于0,且剩余的钱数够剩下人平分到0.01元  
                if(temp*1.0/(count-1) >= 1 && val > 0) {  
                    //System.out.println("生成金额 :" + val + "剩余金额 :" + temp + "剩余人数 :" + (count-1));  
                    break;  
                }  
            }  
            totalVal = totalVal - val;  
        }  
        count--;  
        return val/100.0;  
    }  
}