import (
"fmt"
"math/rand"
"sync"
"time"
)
type RedPack struct {
Id string
Num int // 红包个数
NumDelivered int // 已拆包数量
Amount int // 红包金额
AmountDelivered int // 已发放金额
}
func NewRedPack(num int, amount int) *RedPack {
return &RedPack{Num: num, Amount: amount, NumDelivered: 0, AmountDelivered: 0}
}
func (pack *RedPack) get() int {
if pack.NumDelivered == pack.Num {
return 0
}
// 最后一个红包直接返回
if pack.NumDelivered == pack.Num-1 {
amount := pack.Amount - pack.AmountDelivered
pack.NumDelivered += 1
pack.AmountDelivered = pack.Amount
return amount
}
// 动态计算红包平均值
avg := (pack.Amount - pack.AmountDelivered) / (pack.Num - pack.NumDelivered)
// 随机计算红包金额(1到2倍均值)
rand.Seed(time.Now().UnixNano())
calAmount := rand.Intn(2 * avg)
// 红包金额最少1分
if calAmount == 0 {
calAmount = 1
}
// 保证后续每个人至少有1分
if (pack.Amount - pack.AmountDelivered - calAmount) < (pack.Num - pack.NumDelivered - 1) {
calAmount = pack.Amount - pack.AmountDelivered - (pack.Num - pack.NumDelivered - 1)
}
pack.NumDelivered += 1
pack.AmountDelivered += calAmount
return calAmount
}
func main() {
start:=time.Now().UnixNano()/1e6
wg := &sync.WaitGroup{}
for i := 0; i < 100000; i++ {
wg.Add(1)
go func(wg *sync.WaitGroup) {
redPack := NewRedPack(10, 10000)
total := 0
for i := 0; i < 10; i++ {
amount := redPack.get()
total += amount
}
wg.Done()
}(wg)
}
wg.Wait(
// 6核,耗时约9秒
fmt.Printf("100000个红发发放完毕,耗时:%d ms",(time.Now().UnixNano()/1e6-start))
}
思路
- 必须保证每个红包至少1分钱
有疑问加站长微信联系(非本文作者)