自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Golang中的同步工具Sync.Once詳解

開(kāi)發(fā) 開(kāi)發(fā)工具
Sync.Once的實(shí)現(xiàn)原理是基于原子性操作和鎖的機(jī)制,只有一個(gè)方法Do(f func()),在第一次調(diào)用Do時(shí),會(huì)執(zhí)行函數(shù)f并將Once對(duì)象標(biāo)記為已完成;第二次及以后調(diào)用Do時(shí),將不再執(zhí)行函數(shù)f。

sync.Once

sync.Once是Golang標(biāo)準(zhǔn)庫(kù)中的一個(gè)同步工具,作用是保證指定函數(shù)只被執(zhí)行一次,可以用于并發(fā)安全的單次初始化、單次執(zhí)行等場(chǎng)景。

使用方法和示例

sync.Once的實(shí)現(xiàn)原理是基于原子性操作和鎖的機(jī)制,只有一個(gè)方法Do(f func()),在第一次調(diào)用Do時(shí),會(huì)執(zhí)行函數(shù)f并將once對(duì)象標(biāo)記為已完成;第二次及以后調(diào)用Do時(shí),將不再執(zhí)行函數(shù)f。看個(gè)例子:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var once sync.Once
	onceBody := func() {
		fmt.Println("只執(zhí)行一次")
	}
	done := make(chan bool)

	for i := 0; i < 10; i++ {
		go func() {
			once.Do(onceBody)
			done <- true
		}()
	}
	for i := 0; i < 10; i++ {
		<-done
	}
}

本例中開(kāi)啟了10個(gè)goroutine,每個(gè)goroutine中都調(diào)用了once.Do(onceBody),但onceBody方法只執(zhí)行了一次。

sync.Once內(nèi)部使用了一個(gè)bool類型的標(biāo)志位,記錄了對(duì)應(yīng)函數(shù)是否已經(jīng)被執(zhí)行過(guò)。當(dāng)Do方法第一次被調(diào)用時(shí),該方法會(huì)獲取鎖并檢查標(biāo)志位,如果標(biāo)志位為false,則執(zhí)行函數(shù)并將標(biāo)志位設(shè)置為 true,否則直接返回鎖并退出。通過(guò)原子性的CAS操作進(jìn)行設(shè)置和讀取,保證并發(fā)的正確性。

假如想要實(shí)現(xiàn)一個(gè)對(duì)象的延遲初始化,只有在第一次被訪問(wèn)時(shí)才進(jìn)行初始化操作,可以使用sync.Once來(lái)實(shí)現(xiàn),代碼如下:

type MyObject struct {
  // 懶加載初始化參數(shù) 
  initParams string

  // 初始化后的值
  value string

  // once對(duì)象
  once sync.Once
}

// 初始化函數(shù),只被調(diào)用一次
func (o *MyObject) init() {
  o.value = "initialized with " + o.initParams
}

// 獲取對(duì)象的value字段,如果對(duì)象還沒(méi)有初始化,則初始化之后再返回
func (o *MyObject) Value() string {
  o.once.Do(o.init)
  return o.value
}

使用了sync.Once實(shí)現(xiàn)了對(duì)象的懶加載,保證了并發(fā)訪問(wèn)的安全性和初始化只被執(zhí)行一次。當(dāng)?shù)谝粋€(gè)goroutine調(diào)用Value方法時(shí),會(huì)執(zhí)行init函數(shù),初始化MyObject的value字段,并標(biāo)記MyObject對(duì)象的once已經(jīng)執(zhí)行過(guò)。后續(xù)的其他goroutine再調(diào)用Value方法時(shí),直接返回value字段,不再進(jìn)行初始化。

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2023-06-05 09:23:00

Golang同步工具

2023-06-26 08:28:35

Sync.CondGolang

2024-06-05 11:06:22

Go語(yǔ)言工具

2021-08-29 18:13:03

緩存失效數(shù)據(jù)

2023-03-28 08:20:07

場(chǎng)景sync.Once?系統(tǒng)

2024-01-08 13:40:00

并發(fā)安全? 數(shù)量

2023-06-27 08:45:19

原子操作Golang

2023-05-11 08:00:44

Golangsync.Pool

2024-07-02 08:32:19

2022-06-07 08:55:04

Golang單例模式語(yǔ)言

2010-05-19 10:22:07

2023-07-05 08:38:48

GolangGo語(yǔ)言

2023-12-25 09:58:25

sync包Go編程

2023-08-03 08:48:07

Golang接口

2023-03-30 07:52:03

Golang接口

2023-11-27 15:02:37

BytesGolang

2023-05-29 09:25:38

GolangSelect

2023-08-31 09:28:12

Golang可導(dǎo)出函數(shù)

2023-10-31 09:10:39

2023-06-09 08:16:09

GolangStruct Tag
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)