PHpullh

GO · 고루틴/채널

sync.Once

sync.Once로 초기화 코드를 정확히 한 번만 실행합니다. 싱글턴, 지연 초기화에 사용됩니다.

고루틴/채널중급sync-oncesingletonlazy-initthread-safe

핵심 설명

sync.Once로 초기화 코드를 정확히 한 번만 실행합니다. 싱글턴, 지연 초기화에 사용됩니다.

Go code

package main

import (
	"fmt"
	"sync"
)

type DB struct {
	Name string
}

var (
	dbInstance *DB
	dbOnce     sync.Once
)

func GetDB() *DB {
	dbOnce.Do(func() {
		fmt.Println("DB 초기화 (한 번만 실행)")
		dbInstance = &DB{Name: "PostgreSQL"}
	})
	return dbInstance
}

func main() {
	var wg sync.WaitGroup

	// 10개 고루틴이 동시에 호출해도 1번만 초기화
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			db := GetDB()
			fmt.Printf("고루틴 %d: %s\n", id, db.Name)
		}(i)
	}

	wg.Wait()
}

학습 팁

sync.OnceDo 내부에서 패닉이 발생해도 "이미 실행됨"으로 간주합니다. Go 1.21+의 sync.OnceFunc은 패닉 시 재시도합니다.

주의할 점

sync.Once를 값으로 복사하면 각 복사본이 독립적으로 동작하여 여러 번 실행됩니다. 포인터로 공유하거나 전역으로 선언하세요.

자주 묻는 질문

sync.Once란 무엇인가요?

sync.Once 로 초기화 코드를 정확히 한 번만 실행합니다. 싱글턴, 지연 초기화에 사용됩니다.

sync.Once 학습 시 주의할 점은 무엇인가요?

sync.Once 를 값으로 복사하면 각 복사본이 독립적으로 동작하여 여러 번 실행됩니다. 포인터로 공유하거나 전역으로 선언하세요.

Continue Learning

Go 학습을 이어가세요

총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.