golang學習———sync.Once(2)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

在開發時,我們經常碰到這樣的應用情境:只需要執行或初始化一次,例如,單例模式或是系統開啟時的初始化。一般的語言通用做法是利用互斥操作設定標誌變數,通過判斷標誌變數的值決定是否執行相關代碼;golang語言的實現非常簡單,只需一行代碼,如下:

        import "sync"

var once sync.Once

func init() {

    //初始化代碼

}


once.Do(init) // 只需一行代碼,結構清晰,一目瞭然

那麼once.Do()這個方法是如何?的呢?我們來解析golang實現的一次操作:

    首先, “sync” 是一個引用的包,具體實現在該包中; Once是定義的一個結構體對象,如下:

     type Once struct {

           m Mutex

           done uint32

     }

     看到這裡,我們基本應該可以猜出once.Do()的實現思路,Once.m是一個互斥鎖,在進行Do()操作時,進行互斥操作;Once.done是一個標誌變數,表示是否進行過Do()的操作。Do()的具體實現如下:

    func (o *Once) Do(f func()) {

        if atomic.LoadUint32(&o.done) == 1 {

return

        }

        o.m.Lock()

        defer o.m.Unlock()

        if o.done == 0 {

     defer automic.StoreUint32(&o.done, 1)

             f()

}

    }

    實現思路與我們的猜測基本一致,它引入了原子操作包  import "sync/atomic",通過automic.LoadUint32和automic.StoreUint32操作實現標誌變數Once.done的載入和儲存,這樣更精細化的原子操作的實現能進一步提高系統處理的速度,減少協程對互斥鎖不必要的等待。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.