抽奖要求:
一共N个奖品,对应N个抽奖员工,每个员工只能抽奖一次,重复抽奖会返回已获得的奖品,并且奖品和员工数量一致。
交代完毕,下面说说设计思路;
奖品和员工数量一致,那就说明每个员工都有奖品,在抽奖程序启动时就初始化奖品在奖品池中的随机位置,奖品池的大小与奖品和员工数量一致,然后根据客户端请求到达顺序来确定奖品发放的顺序。
来看看demo源码:
public class Test { private static final CountDownLatch countDownLatch = new CountDownLatch(20); // 模拟请求到达顺序 即奖品位置 private static final AtomicInteger prizeReqIndex = new AtomicInteger(0); // 模拟奖品池 private static final int[] prizePool = new int[20]; // 已抽奖用户抽奖过滤 static ConcurrentHashMap userFilters = new ConcurrentHashMap<>(); public static void main(String[] args) throws InterruptedException { // 初始随机分配奖品位置 initPrizes(); // 模拟抽奖用户 ExecutorService pool = Executors.newFixedThreadPool(20); for (int i = 1; i < 21; i++) { int finalI = i; pool.execute(() -> { countDownLatch.countDown(); int pidx = cj(finalI + ""); System.out.println(finalI + "号用户,抽到的奖品是:" + prizePool[pidx]); }); } // 模拟抽奖用户重复抽奖 for (int i = 1; i < 21; i++) { int finalI = i; pool.execute(() -> { int pidx = cj(finalI + ""); System.out.println(finalI + "号用户,抽到的奖品是:" + prizePool[pidx]); }); } TimeUnit.SECONDS.sleep(5); pool.shutdown(); } // 抽奖和重复抽奖检测 private static int cj(String uid) { synchronized (uid.intern()) { if (userFilters.containsKey(uid)) { System.out.println(uid + "号用户,你已经抽过奖了"); return userFilters.get(uid); } else { int i = prizeReqIndex.getAndIncrement(); userFilters.put(uid, i); return i; } } } // 初始化奖品编号 private static void initPrizes() { Random random = new Random(); // 已存发放的奖品 Set prizeSet = new HashSet<>(); // 一等奖 while (true) { int jpn = random.nextInt(20); if (prizeSet.size() >= 3) { break; } if (!prizeSet.contains(jpn)) { prizePool[jpn] = 1; prizeSet.add(jpn); } } // 二等奖 while (true) { int jpn = random.nextInt(20); if (prizeSet.size() >= 8) { break; } if (!prizeSet.contains(jpn)) { prizePool[jpn] = 2; prizeSet.add(jpn); } } // 三等奖 while (true) { int jpn = random.nextInt(20); if (prizeSet.size() >= 20) { break; } if (!prizeSet.contains(jpn)) { prizePool[jpn] = 3; prizeSet.add(jpn); } } System.out.println("奖品编号:" + Arrays.toString(prizePool)); }
再看看结果:
奖品编号: 数组index=请求顺序,数组value=奖品
这只是一个demo的实例程序,不严谨的地方还请见谅!
留言与评论(共有 0 条评论) “” |