要完成抢红包的功能重点有两个:java
用户对象:包含用户名称,所抢到的金额,最后的提示文言字段算法
package com.xz.core; /** * 抢红包的用户 * @author ibm */ public class User { /** * 用户昵称 */ private String name; /** * 用户抢到的金额 */ private int money; /** * 用户得到系统提示文言 */ private String info; public User(String name, int money, String info) { this.name = name; this.money = money; this.info = info; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMoney() { return money; } public void setMoney(int money) { this.money = money; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } }
并发访问的共享红包对象:这个对象包含了预分配的全部小红包并提供并发控制,用户线程只能经过这个类得到红包多线程
package com.xz.core; import java.util.List; public class Moneys { /** * 预分配的红包金额 */ List<Integer> moneys; Moneys(List<Integer> moneys){ this.moneys = moneys; } /** * 得到红包,若是一个用户得到了红包,改红包将从红包集合中移除 * @return 红包金额 */ public synchronized Integer getMoney(){ if(moneys.size() <= 0){ return 0; } int money = moneys.get(0); moneys.remove(0); return money; } }
用户线程:并发
class GrabRedEnvelopeThread implements Runnable{ /** * 该线程持有的用户对象 */ private User user; /** * 全部线程共享的与分配金额 */ private Moneys moneys; GrabRedEnvelopeThread(User user,Moneys moneys){ this.user = user; this.moneys = moneys; } @Override public void run() { try { int myMoney = moneys.getMoney(); user.setMoney(myMoney); if(myMoney > 0){ user.setInfo(user.getName() + " 得到 " +myMoney); }else { user.setInfo(user.getName() + " 没抢到"); } } catch (Exception e) { e.printStackTrace(); } } }
红包金额分配算法:至关简陋的实现:dom
/** * 获取随机的红包金额 * @param number 红包数量 * @param money 红包金额 * @return 随机红包 */ private Moneys getRandomMoney(int number,int money){ List<Integer> moneys = new ArrayList<>(); int averageMoney = money / number; for (int i = 0; i < number; i++) { if(i == (number - 1)){ moneys.add(money - moneys.stream().mapToInt(m -> m.intValue()).sum()); }else { moneys.add((int)(Math.random() * averageMoney +1)); } } if(moneys.size() != number){ System.out.println("nq"); } return new Moneys(moneys); }
代码模拟器:用于测试的客户端ide
import java.util.*; import java.util.concurrent.CompletableFuture; /** * 抢红包模拟器 * @author ibm */ @SuppressWarnings("all") public class BusinessSimulator { /** * 用户群 */ private List<User> users = Arrays.asList(new User("王一",0,""), new User("牛二",0,""), new User("张三",0,""), new User("李四",0,""), new User("吴五",0,""), new User("赵六",0,""), new User("枸七",0,"")); /** * 发出的金额 */ private int money = 100; /** * 红包数量 */ private int number = 3; public static void main(String[] args) throws InterruptedException { BusinessSimulator simulator = new BusinessSimulator(); simulator.grabRedEnvelope(simulator.users,simulator.money,simulator.number); simulator.users.forEach(u -> { System.out.println(u.getInfo()); }); } /** * 抢红包方法 * @param users 用户群 * @param money 发出的金额 * @param number 红包数量 * @return 用户抢到红包集合 */ private List<User> grabRedEnvelope(List<User> users,int money,int number) throws InterruptedException { //预分配金额 Moneys moneys = getRandomMoney(number, money); List<CompletableFuture> futures = new ArrayList<>(); for (int index = 0; index < users.size(); index++) { Runnable run = new GrabRedEnvelopeThread(users.get(index),moneys); futures.add(CompletableFuture.runAsync(run)); } CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).join(); return users; } }