多线程无锁红包实现方案
多线程无锁红包实现方案
背景
代码
@Data public class RedPacket { //红包总额 private Double total; //红包份数 private Integer counts; //红包分隔之后的载体 private List<Double> values; //用来获取下标 private AtomicInteger taskCounts; //红包公平概率 private Double fairRate; private DecimalFormat decimalFormat =new DecimalFormat("#.00"); public RedPacket(Double total, Integer counts,Double fairRate) { this.total = total; this.counts = counts; taskCounts = new AtomicInteger(counts); dealFairRate(fairRate); caculate(total,counts,this.fairRate); } private void dealFairRate(Double fairRate) { fairRate = fairRate<0?0:fairRate; fairRate = fairRate>1?1:fairRate; this.fairRate = fairRate; } public String get(){ final int flag = taskCounts.getAndDecrement(); if(flag>=0){ return decimalFormat.format(values.get(flag)); }else { return "手速慢了,该红包已经被抢空了"; } } private void caculate(Double total, Integer counts,Double fairRate) { values = doubleMeanMethod(total,counts,fairRate); } public static double nextDouble(final double min,final double max){ return min+((max-min)*new Random().nextDouble()); } public static String format(double value){ return new java.text.DecimalFormat("0.00").format(value); } public static List<Double> doubleMeanMethod(double money, int number,double fairRate){ final ArrayList<Double> doubles = new ArrayList<>(); if (money<=0&&number<1) { return null; } //一般频率均分,其余的随机。可以自己调整平分概率 double avg = money*fairRate; money = money - avg; double avgP = avg/number; double amount,sum = 0; int remainNumber = number; //int i =1; while (remainNumber-->1){ if(fairRate!=1.0){ amount = nextDouble(0.01,money/remainNumber); //sum+=amount+avgP; //System.out.println("第" + i++ + "个人的领取的红包金额为:" + format(amount+avgP)); money-=amount; doubles.add(amount+avgP); }else { doubles.add(avgP); } } doubles.add(money+avgP); //System.out.println("第" + i++ + "个人的领取的红包金额为:" + format(money+avgP)); //sum+=money+avgP; //System.out.println("验证红包总金额为:" + format(sum)); return doubles; } public static void main(String[] args) throws InterruptedException { final RedPacket redPacket = new RedPacket(100.00, 10,0.0); for (int i = 0; i <20 ; i++) { CompletableFuture.runAsync(()->{ final String s = redPacket.get(); System.out.println(s); }); } Thread.sleep(10000); System.out.println("完成"); } }
下一篇:
数据结构 链表的各种插入