Sync.mutex的使用

Go语言的sync包中提供了两种锁类型,sync.mutex和sync.RWmutex,前者是互斥锁,后者是读写锁。

  • 使用Lock()加锁后,不能再继续对其加锁(同一个goroutine中,即:同步调用),否则会panic。只有在unlock()之后才能再次Lock()。异步调用Lock(),是正当的锁竞争,当然不会有panic了。适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁也叫做全局锁。
  • func (m *Mutex) Unlock()用于解锁m,如果在使用Unlock()前未加锁,就会引起一个运行错误。已经锁定的Mutex并不与特定的goroutine相关联,这样可以利用一个goroutine对其加锁,再利用其他goroutine对其解锁。

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func main() {
	var mutex sync.Mutex
	mutex.Lock()
	go func() {
		mutex.Lock()
		fmt.Println("test")

		time.Sleep(time.Second)
		mutex.Unlock()
	}()

	mutex.Unlock()
	time.Sleep(time.Second)
}

用法与其他语言没什么太大不同。

作为struct的一部分来使用

作为structd的一部分来使用,这样这个struct 就会防止被多线程更改数据。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

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

type Book struct {
	bookname string
	sync.Mutex
}

func (bb *Book) SetName(wg *sync.WaitGroup, name string) {
	bb.Lock()
	defer bb.Unlock()
	fmt.Println("tes1", name)
	bb.bookname = name
	fmt.Println("tes1", name)
	wg.Done()

}
func main() {
	wg := &sync.WaitGroup{}
	wg.Add(3)
	bk := Book{}
	books := []string{"111", "222", "3333"}
	for _, bookname := range books {
		go bk.SetName(wg, bookname)
	}
	wg.Wait()
}