golang的多线程固然好用,但是有时候需要对数据进行上锁,防止数据被其它线程更改。那么sync包下的Mutex非常好用。

Mutex是一个互斥锁。可以作为struct的一部分,这样这个struct就会防止被多线程更改数据。

来个例子:

package main  
  
import (  
    "fmt"  
    "sync"  
    "time"  
)  
  
type User struct {  
    Name   string  
    Locker *sync.Mutex  
}  
  
func (u *User) SetName(wati *sync.WaitGroup, name string) {  
    defer func() {  
        fmt.Println("Unlock set name:", name)  
        u.Locker.Unlock()  
        wati.Done()  
    }()  
  
    u.Locker.Lock()  
    fmt.Println("Lock set name:", name)  
    time.Sleep(1 * time.Second)  
    u.Name = name  
}  
  
func (u *User) GetName(wati *sync.WaitGroup) {  
    defer func() {  
        fmt.Println("Unlock get name:", u.Name)  
        u.Locker.Unlock()  
        wati.Done()  
    }()  
  
    u.Locker.Lock()  
    fmt.Println("Lock get name:", u.Name)  
    time.Sleep(1 * time.Second)  
}  
  
func main() {  
    user := User{}  
    user.Locker = new(sync.Mutex)  
    wait := &sync.WaitGroup{}  
    names := []string{"a", "b", "c"}  
    for _, name := range names {  
        wait.Add(2)  
        go user.SetName(wait, name)  
        go user.GetName(wait)  
    }  
  
    wait.Wait()  
} 

输出结果 : 

Lock set name: a  
Unlock set name: a  
Lock get name: a  
Unlock get name: a  
Lock set name: b  
Unlock set name: b  
Lock get name: b  
Unlock get name: b  
Lock set name: c  
Unlock set name: c  
Lock get name: c  
Unlock get name: c  

程序很简单,就是防止在读取姓名的时候,被其它线程更改。这个程序还有些问题,不过总得来说,就是想演示一下Mutex的用途。可以让一个struct只被一个线程操作,而其它的线程就会阻塞。

原文连接:http://www.liguosong.com/2014/05/07/golang-sync-mutex/