go-使用通道模拟抢到活动

发布时间 2023-12-28 14:48:44作者: 青烟绕指柔
package main

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"math/rand"
	"sync"
	"time"
)

// 用户结构体

type User struct {
	Id      int
	Name    string
	Tel     string
	Address string
}

// 使用通道来模拟商品抢购活动,用户量1000,商品数量是10
var wg sync.WaitGroup

// 全局变量存储数据库连接
var db *gorm.DB

// 连接数据库
func init() {
	dsn := "root:root@tcp(127.0.0.1:8889)/2112a"
	db, _ = gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

func main() {

	userCount := 1000000 //用户人数
	productCount := 10   //商品数量

	users := make(chan User, userCount)     //用户通道
	product := make(chan int, productCount) //商品通道

	// 将商品编号写入通道
	for i := 1; i <= productCount; i++ {
		product <- i
	}

	// 模拟用户信息 存入用户通道
	for i := 1; i <= userCount; i++ {
		user := User{
			Name:    fmt.Sprintf("用户%d", i),
			Tel:     TelNumber(),
			Address: fmt.Sprintf("上海市奉贤区海湾镇XXXX号-%d", i),
		}
		users <- user
	}
	close(users) //关闭通道

	// 模拟抢购
	for user := range users {
		wg.Add(1)
		go func(u User) {
			defer wg.Done()
			select {
			case <-product:
				fmt.Printf("%s请购成功,手机号为%s,收获地址为%s\n", u.Name, u.Tel, u.Address)
				Insert(u)
			default:
				fmt.Printf("%s请购失败\n", u.Name)
			}
		}(user)
	}
	wg.Wait()

	fmt.Println("活动结束")
}

// 随机生成11位手机号

func TelNumber() string {
	rand.Seed(time.Now().UnixNano())                                                         // 设置随机数种子
	prefix := []string{"130", "131", "132", "133", "135", "137", "138", "170", "187", "189"} // 手机号前缀
	mobile := prefix[rand.Intn(len(prefix))]                                                 // 随机生成手机号前缀
	for i := 0; i < 8; i++ {
		number := rand.Intn(10) // 生成0-9之间的随机数字
		mobile += fmt.Sprintf("%d", number)
	}
	return mobile
}

// 添加入库

func Insert(u User) bool {
	err := db.Create(&u).Error
	if err != nil {
		return false
	} else {
		return true
	}
}