Тип sync.Pool
Тип sync.Pool представляет собой пул временных объектов,
которые могут быть переиспользованы для снижения количества
выделений памяти и нагрузки на сборщик мусора.
Пул безопасен для конкурентного использования из нескольких горутин.
Основное предназначение sync.Pool - хранение объектов,
создание которых требует значительных ресурсов, для их повторного
использования. Пул автоматически удаляет объекты при необходимости.
Синтаксис
var pool sync.Pool
pool.New = func() interface{} {
return new(MyType)
}
Метод Get - получение объекта из пула
Метод Get возвращает объект из пула. Если в пуле нет объектов,
то вызывается функция New для создания нового объекта.
Возвращаемое значение имеет тип interface{},
поэтому его необходимо привести к нужному типу.
Метод Put - возвращение объекта в пул
Метод Put помещает объект обратно в пул для последующего
переиспользования. После вызова Put объект может быть
использован другим потребителем, поэтому не следует продолжать
использовать объект после его возврата в пул.
Пример
Давайте создадим пул для переиспользования буферов bytes.Buffer:
package main
import (
"bytes"
"fmt"
"sync"
)
func main() {
var pool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
buf := pool.Get().(*bytes.Buffer)
buf.WriteString("Hello, World!")
fmt.Println(buf.String())
buf.Reset()
pool.Put(buf)
}
Результат выполнения кода:
"Hello, World!"
Пример
Давайте рассмотрим пример с конкурентным использованием пула:
package main
import (
"fmt"
"sync"
)
func main() {
var pool = sync.Pool{
New: func() interface{} {
return make([]int, 0, 10)
},
}
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
slice := pool.Get().([]int)
slice = append(slice, id)
fmt.Printf("Goroutine %d: %v\n", id, slice)
slice = slice[:0]
pool.Put(slice)
}(i)
}
wg.Wait()
}
Результат выполнения кода:
"Goroutine 2: [2]"
"Goroutine 0: [0]"
"Goroutine 1: [1]"
Пример
Давайте продемонстрируем, как sync.Pool автоматически
очищает объекты при необходимости:
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
var pool = sync.Pool{
New: func() interface{} {
return "new object"
},
}
pool.Put("cached object")
fmt.Println(pool.Get())
fmt.Println(pool.Get())
runtime.GC()
fmt.Println(pool.Get())
}
Результат выполнения кода:
"cached object"
"new object"
"new object"
Смотрите также
-
метод
sync.Pool.Get,
который получает объект из пула -
метод
sync.Pool.Put,
который возвращает объект в пул -
тип
sync.Mutex,
который обеспечивает взаимное исключение для доступа к данным -
тип
sync.WaitGroup,
который ожидает завершения группы горутин