Golang一个协程写,一个协程读,这四个类型哪个不用上锁

47 阅读1分钟

先看代码,结论是切片,变量和struct都可以不用上锁,当只有一个协程写的时候。但是map是不行的。

package main

import (
	"fmt"
	"math/rand"
	"time"
)

var (
	globalVar    int      // 全局变量
	globalSlice  []int    // 全局切片
	globalStruct struct { // 全局结构体
		Field1 int
		Field2 string
	}
	globalMap map[int]int // 全局map
)

func modifyGlobalVar() {
	for {
		globalVar = rand.Intn(100) // 随机赋值
		time.Sleep(time.Millisecond * 10)
	}
}

func readGlobalVar() {
	for {
		fmt.Printf("Read globalVar: %d\n", globalVar)
		time.Sleep(time.Millisecond * 20)
	}
}

func modifyGlobalSlice() {
	for {
		globalSlice = append(globalSlice, rand.Intn(100)) // 随机追加值
		time.Sleep(time.Millisecond * 10)
	}
}

func readGlobalSlice() {
	for {
		fmt.Printf("Read globalSlice: %v\n", globalSlice)
		time.Sleep(time.Millisecond * 20)
	}
}

func modifyGlobalStruct() {
	for {
		globalStruct.Field1 = rand.Intn(100)
		globalStruct.Field2 = fmt.Sprintf("Value%d", rand.Intn(100))
		time.Sleep(time.Millisecond * 10)
	}
}

func readGlobalStruct() {
	for {
		fmt.Printf("Read globalStruct: %+v\n", globalStruct)
		time.Sleep(time.Millisecond * 20)
	}
}

func modifyGlobalMap() {
	for {
		key := rand.Intn(10)
		globalMap[key] = rand.Intn(100) // 随机设置键值
		time.Sleep(time.Millisecond * 10)
	}
}

func readGlobalMap() {
	for {
		fmt.Printf("Read globalMap: %v\n", globalMap)
		time.Sleep(time.Millisecond * 20)
	}
}

func main() {
	// 初始化全局map
	globalMap = make(map[int]int)

	// 启动全局变量测试
	go modifyGlobalVar()
	go readGlobalVar()

	// 启动全局切片测试
	go modifyGlobalSlice()
	go readGlobalSlice()

	// 启动全局结构体测试
	go modifyGlobalStruct()
	go readGlobalStruct()

	// 启动全局map测试
	go modifyGlobalMap()
	go readGlobalMap()

	// 主程序运行20秒以观察效果
	time.Sleep(60 * time.Second)
}