sync 的type
type Locker
Locker 接口代表一个可以加锁和解锁的对象
type Locker interface {
Lock()
Unlock()
}
type Once
Once是只执行一次动作的对象
type Once struct {
m Mutex
done uint32
}
func(o *Once) Do(f func())
如果once do 被多次调用,只有第一次调用会执行f,即使f每次调用Do 提供的f值不同。需要给每个要执行仅一次的函数都建立一个Once类型的实例。
实现单例设计模式
example
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
//Once 是一个可以被多次调用但是只执行一次,若每次调用Do时传入参数f不同,但是只有第一个才会被执行
//func (o *Once) Do(f func())
var once sync.Once
func main() {
onceBody:=func(){
fmt.Println("Only once")
}
done:=make(chan bool)
for i:=0;i<10;i++{
go func() {
once.Do(onceBody)
done<-true
}()
}
for i:=0;i<10;i++{
<-done
}
}
只执行一次
type Mutex
Mutex是一个互斥锁,可以创建为其他结构体的字段;零值为解锁状态。Mutex类型的锁和线程无关,可以由不同的线程加锁和解锁
type Mutex struct {
state int32
sema uint32
}
type WaitGroup
WaitGroup用于等待一组线程的结束。父线程调用Add方法来设定应等待的线程的数量。每个被等待的线程在结束时应调用Done方法。同时,主线程里可以调用Wait方法阻塞至所有线程结束。
func (*WaitGroup) Add
Add方法向内部计数加上delta,delta可以是负数;如果内部计数器变为0,Wait方法阻塞等待的所有线程都会释放,如果计数器小于0,方法panic。注意Add加上正数的调用应在Wait之前,否则Wait可能只会等待很少的线程。一般来说本方法应在创建新的线程或者其他应等待的事件之前调用。
func (*WaitGroup) Done
Done方法减少WaitGroup计数器的值,应在线程的最后执行。
func (*WaitGroup) Wait
Wait方法阻塞直到WaitGroup计数器减为0。
example
func main() {
var wg sync.WaitGroup
var urls=[]string{
"http://www.golang.org/",
"http://www.baidu.com/",
"http://www.baidu.com/",
}
for _,url:=range urls{
wg.Add(1)
go func(url string) {
defer wg.Done()
a,_:=http.Get(url)
fmt.Println(time.Now())
fmt.Println(a.Header)
}(url)
}
fmt.Println(time.Now())
wg.Wait()
}