github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/14_concurrent/doublecheck/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  )
     7  
     8  type Once struct {
     9  	m    sync.Mutex
    10  	done uint32
    11  }
    12  
    13  /*
    14  A: 不能编译
    15  B: 可以编译,正确实现了单例
    16  C: 可以编译,不正确的单例实现 答案,以为done==1会有线程读写冲突
    17  D: 可以编译,但是程序运行会panic
    18  */
    19  func (o *Once) Do(f func()) {
    20  	if o.done == 1 {
    21  		return
    22  	}
    23  	o.m.Lock()
    24  	defer o.m.Unlock()
    25  	if o.done == 0 {
    26  		o.done = 1
    27  		f()
    28  	}
    29  }
    30  
    31  /*
    32  A: 不能编译
    33  B: 可以编译,正确实现了单例
    34  C: 可以编译,不正确的单例实现
    35  D: 可以编译,但是程序运行会panic
    36  */
    37  
    38  func main() {
    39  	once := &Once{}
    40  	for i := 0; i < 10; i++ {
    41  		go once.Do(func() {
    42  			fmt.Println("我执行了")
    43  		})
    44  	}
    45  }