1. sync.Once的功用是什麼?
A. 只執行ㄧ次函數。
更具體說,需要執行函數的時候,呼叫sync.Once的Do方法,該方法就會執行函數,且只執行一次
B. sync.Once類型屬於結構體類型,為開箱即用。此類型包含sync.Mutex的字段。
type Once struct {
m Mutex
done uint32
}
C. 這個類型的Do方法,只接受一個參數,而這個參數的類型必須是func(),無參數和結果聲明的函數。
2. Do方法的功能,並不是對每一種參數函數都只執行ㄧ次,而是只執行"第一次被調用傳入"的函數,並且之後不會再執行任何參數函數。
如果,有多個只需要執行ㄧ次的函數,就必須為它們每一個都寫一個sync.Once類型的值。
3. 程式碼範例
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter uint32
var once sync.Once
once.Do(func() {
atomic.AddUint32(&counter, 1)
})
fmt.Printf("The counter: %d\n", counter)
once.Do(func() { // 沒有執行。上面已經用過這個Once類型的變數,就不會再執行
atomic.AddUint32(&counter, 2)
})
fmt.Printf("The counter: %d\n", counter)
var once2 sync.Once // 想要再執行其它函數,就必須再寫一個sync.Once類型的變數
once2.Do(func() {
atomic.AddUint32(&counter, 5)
})
fmt.Printf("The counter: %d\n", counter)
}
https://play.golang.org/p/P5jBkCzr1LB
參考來源:
郝林-Go语言核心36讲
https://github.com/hyper0x/Golang_Puzzlers
https://golang.org/pkg/cmd/go/internal/test/