要完成搶紅包的功能重點有兩個: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; } }