欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解Go語言中對象池的正確打開方式

 更新時間:2025年02月07日 08:18:31   作者:燭陰  
對象池是一種設(shè)計模式,它維護(hù)一組已經(jīng)創(chuàng)建好的對象,當(dāng)需要使用對象時,直接從對象池中獲取,使用完畢后再放回對象池,而不是頻繁地創(chuàng)建和銷毀對象,下面我們就來看看Go語言中對象池的具體使用吧

什么是對象池

對象池是一種設(shè)計模式,它維護(hù)一組已經(jīng)創(chuàng)建好的對象,當(dāng)需要使用對象時,直接從對象池中獲取,使用完畢后再放回對象池,而不是頻繁地創(chuàng)建和銷毀對象。 這樣可以顯著減少 GC 的壓力,提高程序的性能。

為什么不用 sync.Pool

sync.Pool 是 Go 標(biāo)準(zhǔn)庫提供的對象池實現(xiàn),但它有一些限制:

  • GC 不確定性: sync.Pool 中的對象可能會被 GC 回收,導(dǎo)致每次獲取對象都需要重新創(chuàng)建,失去了對象池的意義。
  • 適用場景有限: sync.Pool 更適合于臨時對象的復(fù)用,對于需要長期存在的對象,效果不佳。
  • 控制力不足: 無法精確控制對象池的大小和對象的生命周期。

因此,在某些場景下,我們需要自定義對象池,以獲得更高的性能和控制力。

手?jǐn)]對象池:原理與實現(xiàn)

下面,我們就來手?jǐn)]一個簡單的對象池,并分析其原理。

1. 定義對象池結(jié)構(gòu)體

package main

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

type Pool struct {
	objects chan interface{}   // 使用 channel 存儲對象
	factory func() interface{} // 創(chuàng)建對象的工廠函數(shù)
	mu      sync.Mutex         // 保護(hù)對象池
}

var g_index int = 0

func NewPool(size int, factory func() interface{}) *Pool {
	if size <= 0 {
		panic("對象池大小必須大于 0")
	}
	pool := make(chan interface{}, size)
	for i := 0; i < size; i++ {
		pool <- factory() // 預(yù)先創(chuàng)建對象并放入對象池
	}
	return &Pool{
		objects: pool,
		factory: factory,
	}
}

func (p *Pool) Get() interface{} {
	select {
	case obj := <-p.objects:
		return obj // 從對象池中獲取對象
	default:
		// 對象池為空,創(chuàng)建新對象
		fmt.Println("create new object")
		p.mu.Lock()
		defer p.mu.Unlock()
		return p.factory()
	}
}

func (p *Pool) Put(obj interface{}) error {
	select {
	case p.objects <- obj: // 對象放回對象池
		return nil
	default:
		// 對象池已滿,丟棄對象
		obj2 := obj.(*MyObject)
		fmt.Println("pool is full, discard object", obj2.index)
		obj = nil
		return errors.New("pool is full")
	}
}

func (p *Pool) Len() int {
	return len(p.objects)
}

type MyObject struct {
	Data  string
	index int
}

func main() {
	// 創(chuàng)建對象工廠
	objectFactory := func() interface{} {
		g_index += 1
		return &MyObject{Data: "Initial Data", index: g_index}
	}

	// 創(chuàng)建對象池,大小為 10
	pool := NewPool(10, objectFactory)

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(idx int) {
			fmt.Println("pool len:", pool.Len())
			obj := pool.Get().(*MyObject)
			defer func() {
				wg.Done()
				pool.Put(obj)
			}()
			fmt.Println("from :", obj.Data, obj.index, idx)
			time.Sleep(time.Millisecond * 2) // 模擬一些工作
		}(i)
	}
	wg.Wait()
}

代碼解釋:

  • ObjectPool 結(jié)構(gòu)體包含一個 pool channel,用于存儲對象。
  • factory 是一個函數(shù),用于創(chuàng)建新的對象。
  • NewObjectPool 函數(shù)用于創(chuàng)建對象池,并預(yù)先創(chuàng)建指定數(shù)量的對象放入對象池。
  • Get 函數(shù)用于從對象池中獲取對象。如果對象池為空,則調(diào)用 factory 創(chuàng)建新的對象。
  • Put 函數(shù)用于將對象放回對象池。如果對象池已滿,則丟棄對象。
  • 定義了一個 MyObject 結(jié)構(gòu)體,作為對象池中存儲的對象類型。
  • 創(chuàng)建一個 objectFactory 函數(shù),用于創(chuàng)建 MyObject 對象。
  • 創(chuàng)建一個大小為 10 的對象池,并傳入 objectFactory 函數(shù)。
  • 從對象池中獲取對象,修改對象的數(shù)據(jù),然后將對象放回對象池。
  • 再次從對象池中獲取對象,可以看到對象的數(shù)據(jù)已經(jīng)被修改,說明對象被成功復(fù)用。

總結(jié)

通過手?jǐn)]對象池,我們不僅可以更好地理解對象池的原理,還可以根據(jù)實際需求定制對象池,以獲得更高的性能和控制力。 在需要頻繁創(chuàng)建和銷毀對象的場景下,使用對象池可以顯著提高程序的性能,告別 GC 噩夢!

到此這篇關(guān)于一文詳解Go語言中對象池的正確打開方式的文章就介紹到這了,更多相關(guān)Go對象池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語言中反射機(jī)制的三種使用場景

    go語言中反射機(jī)制的三種使用場景

    本文主要介紹了go語言中反射機(jī)制的三種使用場景,包括JSON解析、ORM框架和接口適配,具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • Golang?range?slice?與range?array?之間的區(qū)別

    Golang?range?slice?與range?array?之間的區(qū)別

    這篇文章主要介紹了Golang?range?slice?與range?array?之間的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • 詳解golang開發(fā)中http請求redirect的問題

    詳解golang開發(fā)中http請求redirect的問題

    這篇文章主要介紹了詳解golang開發(fā)中http請求redirect的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • GO中Json解析的幾種方式

    GO中Json解析的幾種方式

    本文主要介紹了GO中Json解析的幾種方式,詳細(xì)的介紹了幾種方法,?文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • 詳解Go語言中的作用域和變量隱藏

    詳解Go語言中的作用域和變量隱藏

    這篇文章主要為大家介紹了Go語言中的作用域和變量隱藏,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Go語言有一定的幫助,感興趣的小伙伴可以了解一下
    2022-04-04
  • Golang學(xué)習(xí)之內(nèi)存逃逸分析

    Golang學(xué)習(xí)之內(nèi)存逃逸分析

    內(nèi)存逃逸分析是go的編譯器在編譯期間,根據(jù)變量的類型和作用域,確定變量是堆上還是棧上。本文將帶大家分析一下Golang中的內(nèi)存逃逸,需要的可以了解一下
    2023-01-01
  • golang 如何獲取文件夾下面的文件列表

    golang 如何獲取文件夾下面的文件列表

    這篇文章主要介紹了golang 獲取文件夾下面的文件列表方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 從零封裝Gin框架實現(xiàn)日志初始化及切割歸檔功能

    從零封裝Gin框架實現(xiàn)日志初始化及切割歸檔功能

    這篇文章主要為大家介紹了從零封裝Gin框架實現(xiàn)日志初始化及切割歸檔功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • go語言實現(xiàn)AES加密的方法

    go語言實現(xiàn)AES加密的方法

    這篇文章主要介紹了go語言實現(xiàn)AES加密的方法,實例分析了Go語言的加密技巧,需要的朋友可以參考下
    2015-03-03
  • GoLang string與strings.Builder使用對比詳解

    GoLang string與strings.Builder使用對比詳解

    這篇文章主要介紹了GoLang string與strings.Builder使用對比,Builder 用于使用 Write 方法有效地構(gòu)建字符串。它最大限度地減少了內(nèi)存復(fù)制。零值可以使用了。不要復(fù)制非零生成器
    2023-03-03

最新評論