0
点赞
收藏
分享

微信扫一扫

golang入门笔记—锁

钵仔糕的波波仔 2022-04-13 阅读 62
golang
//互斥锁
//互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。
type Mutex struct{
	state int32
	sema  uint32
}

var x=0
var wg sync.WaitGroup
var lock sync.Mutex

func add(){
	for i:=0;i<50000;i++{
	    lock.Lock() //加锁互斥访问x
		x=x+1
		lock.Unlock()//释放锁
	}
	wg.Done()
}

func main(){
	wg.Add(2)
	go add()
	go add()
	wg.Wait()
	fmt.Println(x)
}
//读写互斥锁
package main

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

var (
	x      = 0
	wg     sync.WaitGroup
	lock   sync.Mutex
	rwLock sync.RWMutex
)

//读操作加读锁
func read() {
	defer wg.Done()
	rwLock.RLock()
	fmt.Println(x)
	time.Sleep(time.Millisecond)
	rwLock.RUnlock()
}

func write() {
	defer wg.Done()
	rwLock.Lock()
	fmt.Println(x)
	x = x + 1
	time.Sleep(time.Millisecond)
	rwLock.Unlock()
}

func main() {
	start := time.Now()
	for i := 0; i < 100; i++ {
		go write()
		wg.Add(1)
	}
	for i := 0; i < 1000; i++ {
		go read()
		wg.Add(1)
	}
	wg.Wait()
	fmt.Println(time.Now().Sub(start))
}
var icons map[string]image.Image

var loadIconsOnce sync.Once

func loadIcons(){
	icons =map[string]image.Image{
		"left": loadIcon("left.png"),
        "up": loadIcon("up.png"),
		"right":loadIcon("right.png"),
		"down":loadIcon("down.png"),
	}
}

//Icon是并发安全的
func Icon(name string)image.Image{
	loadIconsOnce.Do(loadIcons)//多个Icon并发时,loadIcons只执行一次
	return icons[name]
}
//sync.Map
package main

//go内置map不是并发安全的
//需要为map加锁来保证并发的安全性

import (
	"fmt"
	"strconv"
	"sync"
)

var m2 = sync.Map{}

func main() {
	wg := sync.WaitGroup{}
	for i := 0; i < 20; i++ {
		wg.Add(1)
		go func(n int) {
			key := strconv.Itoa(n)
			m2.Store(key, n) //必须使用sync.Map内置的Store方法设置键值对
			value, _ := m2.Load(key) //必须使用sync.Map提供的Load方法提供key取值
			fmt.Printf("k=%v,v=%v\n", key, value)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

//atomic原子操作
package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

//原子操作
var x int64

var wg sync.WaitGroup
var lock sync.Mutex

func add() {
	lock.Lock()
	x = x + 1
	lock.Unlock()
	wg.Done()
} //利用锁来实现对x的互斥

func add2() {
	atomic.AddInt64(&x, 1)
	wg.Done()
} //利用atomic包中的加法来实现原子操作加法

func main() {
	wg.Add(100000)
	for i := 0; i < 100000; i++ {
		go add()
	}
	fmt.Println(x)
}

举报

相关推荐

0 条评论