java多執行緒實現搶紅包
阿新 • • 發佈:2018-12-22
在準備寫這個程式碼之前,我著實的複習和加深了對執行緒操作的使用,同步和資料共享!
說一下程式碼的思路:
首先搶紅包,人、紅包抽象為兩個物件,人(獲取到紅包)紅包(總額,數量,提供生成隨機金額方法)
其中,生成隨機紅包有兩種方案,第一種:獲取的時候生成,第二種:先生成好所有的紅包
對於兩種方案都涉及到資料同步和共享,紅包的總額就是一個共享資料,獲取隨機生成的紅包金額方法需要加鎖,保證生成隨機金額時只有一個執行緒在操作。
坑的點: 1、如果錢數0.04,數量4個,類似這樣的需要特殊處理
2、為了生成錢數的概率達到儘可能的平等 val = new Random().nextInt(totalVal/count);
3、便於金額的操作,換算為整形進行操作
4、隨機生成的金額可能是0,需要進行判斷處理
以下就是程式碼,如果有哪裡不對,請大佬指教!
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; } }
程式碼執行結果圖: