chan 实现简单卖票功能

发布时间 2023-06-01 11:22:30作者: 晚秋时节

一、chan代码

package main

import (
	"fmt"
	"sync"
)

var code sync.WaitGroup

func main() {

	// 创建一个int类型通道
	ticketChan := make(chan int)

	// 判断还有几个线程
	code.Add(5)

	// 启动五个协程
	go codeSale("售票口1", ticketChan)
	go codeSale("售票口2", ticketChan)
	go codeSale("售票口3", ticketChan)
	go codeSale("售票口4", ticketChan)
	go codeSale("售票口5", ticketChan)
	for i := 0; i < 10; i++ {
		//fmt.Println("main", i+1)

		// 给通道赋值
		ticketChan <- i + 1
	}
	// 关闭通道
	close(ticketChan)

	// 待 wg 归零,才会继续向下执行
	code.Wait()
}

func codeSale(name string, ch chan int) {
	// 协程结束
	defer code.Done()
	for {
		ans, ok := <-ch
		//fmt.Printf("%s,票是否卖完%t\n", name, !ok)
		if !ok {
			fmt.Println(name + "已经关闭")
			break
		}
		fmt.Printf("%s售出了%d号票\n", name, ans)
	}
}

二、锁代码

package main

import (
	"fmt"
	"sync"
	"time"
)

// 加锁
var mutex sync.Mutex

var wW sync.WaitGroup

// 总票数 10张
var ticket int = 10

func main() {
	wW.Add(4)
	go sale("张三")
	go sale("李四")
	go sale("王五")
	go sale("赵六")

	wW.Wait()

	//time.Sleep(time.Second * 3)
}

// 卖票
func sale(name string) {
	defer wW.Done()
	for {
		// 加锁
		mutex.Lock()
		if ticket > 0 {
			time.Sleep(time.Millisecond)
			fmt.Println(name+"拿到了一张票", ticket)
			ticket--
		} else {
			fmt.Println("票卖完了")
			// 解锁
			mutex.Unlock()
			break
		}
		// 解锁
		mutex.Unlock()
	}
}