РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
855 of 1593 menu

Метод sync.Pool.Get

Метод sync.Pool.Get извлекает объект из пула. Если в пуле есть доступные объекты, метод возвращает один из них. Если пул пуст, метод вызывает функцию New, указанную при создании пула, и возвращает созданный объект. Метод возвращает значение типа interface{}, поэтому результат требует приведения к нужному типу.

Синтаксис

pool.Get()

Пример

Давайте создадим пул для объектов типа bytes.Buffer и получим объект из пула:

package main import ( "bytes" "fmt" "sync" ) func main() { pool := &sync.Pool{ New: func() interface{} { return bytes.NewBuffer([]byte{}) }, } buf := pool.Get().(*bytes.Buffer) defer pool.Put(buf) buf.WriteString("Hello, World!") fmt.Println(buf.String()) }

Результат выполнения кода:

"Hello, World!"

В этом примере мы создаем пул с функцией New, которая создает новый буфер. Метод Get возвращает объект из пула или создает новый через New, после чего мы используем буфер для записи строки.

Пример

Давайте рассмотрим, как работает получение объектов при наличии и отсутствии объектов в пуле:

package main import ( "fmt" "sync" ) func main() { pool := &sync.Pool{ New: func() interface{} { return 0 }, } // Пул пуст - Get создает новый объект val1 := pool.Get().(int) fmt.Println(val1) // Помещаем объект обратно в пул pool.Put(42) // Get возвращает существующий объект val2 := pool.Get().(int) fmt.Println(val2) // Пул снова пуст - создается новый объект val3 := pool.Get().(int) fmt.Println(val3) }

Результат выполнения кода:

0 42 0

При первом вызове пул пуст, поэтому создается новый объект через New. После помещения объекта в пул, метод Get возвращает его. После повторного извлечения пул становится пустым, и снова создается новый объект.

Пример

Давайте рассмотрим практический пример с обработкой большого количества данных:

package main import ( "fmt" "sync" ) type Data struct { value int } func main() { pool := &sync.Pool{ New: func() interface{} { return &Data{} }, } var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func(id int) { defer wg.Done() // Получаем объект из пула data := pool.Get().(*Data) defer pool.Put(data) // Используем объект data.value = id fmt.Printf("goroutine %d: data.value = %d\n", id, data.value) }(i) } wg.Wait() }

Результат выполнения кода (порядок может варьироваться):

"goroutine 9: data.value = 9" "goroutine 0: data.value = 0" "goroutine 1: data.value = 1" "goroutine 2: data.value = 2" "goroutine 3: data.value = 3" "goroutine 4: data.value = 4" "goroutine 5: data.value = 5" "goroutine 6: data.value = 6" "goroutine 7: data.value = 7" "goroutine 8: data.value = 8"

В этом примере несколько горутин используют sync.Pool для получения объектов. Метод Get возвращает объект, который может быть ранее использован другой горутиной, поэтому важно правильно его сбросить перед использованием.

Смотрите также

  • метод sync.Pool.Put,
    который возвращает объект обратно в пул
  • тип sync.Pool,
    предоставляющий пул временных объектов
  • механизм горутин,
    которые часто используют пулы для оптимизации
  • пакет sync,
    содержащий примитивы синхронизации
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить