Тип atomic.Value
Тип atomic.Value из пакета sync/atomic предоставляет
атомарное хранилище для значений любого типа. Он гарантирует,
что операции записи и чтения будут выполнены безопасно при
конкурентном доступе. Основное преимущество atomic.Value
заключается в том, что он может хранить значения разных типов,
но при этом каждое новое значение должно иметь тот же тип,
что и первое сохраненное.
Синтаксис
var v atomic.Value
v.Store(value) // сохранение значения
val := v.Load() // загрузка значения
Метод Store сохраняет значение в atomic.Value,
а метод Load возвращает сохраненное значение.
Также доступен метод Swap, который сохраняет новое
значение и возвращает старое.
Пример
Давайте создадим atomic.Value для хранения строки
и выполним атомарную запись и чтение:
package main
import (
"fmt"
"sync/atomic"
)
func main() {
var v atomic.Value
// сохраняем строку
v.Store("Hello, World!")
// загружаем значение
res := v.Load()
fmt.Println(res)
}
Результат выполнения кода:
"Hello, World!"
Пример
Теперь рассмотрим пример с конкурентным доступом.
Несколько горутин будут безопасно обновлять значение
с помощью atomic.Value:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var v atomic.Value
v.Store("initial value")
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
newVal := fmt.Sprintf("value from goroutine %d", id)
v.Store(newVal)
fmt.Printf("Goroutine %d stored: %s\n", id, v.Load())
}(i)
}
wg.Wait()
fmt.Println("Final value:", v.Load())
}
Результат выполнения кода:
"Goroutine 4 stored: value from goroutine 4"
"Goroutine 0 stored: value from goroutine 0"
"Goroutine 1 stored: value from goroutine 1"
"Goroutine 2 stored: value from goroutine 2"
"Goroutine 3 stored: value from goroutine 3"
"Final value: value from goroutine 3"
Обратите внимание, что порядок выполнения горутин
может быть разным, но все операции с atomic.Value
безопасны.
Пример
Попробуем сохранить в atomic.Value значение
другого типа после того, как уже было сохранено
значение типа int:
package main
import (
"fmt"
"sync/atomic"
)
func main() {
var v atomic.Value
// сохраняем целое число
v.Store(42)
// пытаемся сохранить строку - будет паника
// v.Store("string")
// загружаем значение
res := v.Load()
fmt.Printf("Type: %T, Value: %v\n", res, res)
}
Результат выполнения кода:
"Type: int, Value: 42"
Важно помнить, что если раскомментировать строку с сохранением строки, программа вызовет панику, так как типы не совпадают.
Смотрите также
-
тип
atomic.Bool,
который представляет атомарное логическое значение -
тип
atomic.Int32,
который представляет атомарное 32-битное целое число -
тип
atomic.Int64,
который представляет атомарное 64-битное целое число -
тип
atomic.Pointer,
который представляет атомарный указатель на значение