[go学习笔记]三十、go语言中如何实现对象池?

137 阅读1分钟

示例代码请访问:github.com/wenjianzhan…

对象池

obj_pool.go

package obj_pool

import (
	"errors"
	"time"
)

type ReusableObj struct {
}

type ObjPool struct {
	bufChan chan *ReusableObj
}

func NewObjPool(numOfObj int) *ObjPool {
	objPool := ObjPool{}
	objPool.bufChan = make(chan *ReusableObj, numOfObj)
	for i := 0; i < numOfObj; i++ {
		objPool.bufChan <- &ReusableObj{}
	}
	return &objPool
}

func (p *ObjPool) GetObj(timeout time.Duration) (*ReusableObj, error) {
	select {
	case ret := <-p.bufChan:
		return ret, nil
	case <-time.After(timeout):
		return nil, errors.New("timeout")

	}
}

func (p *ObjPool) ReleaseObj(obj *ReusableObj) ( error) {
	select {
	case p.bufChan <- obj:
		return nil
	default:
		return errors.New("overflow")

	}
}

obj_pool_test.go

package obj_pool

import (
	"fmt"
	"testing"
	"time"
)

func TestObjPool(t *testing.T) {
	pool := NewObjPool(10)
	//if err := pool.ReleaseObj(&ReusableObj{}); err != nil {
	//	t.Error(err)
	//}
	for i := 0; i < 11; i++ {
		if v, err := pool.GetObj(time.Second * 1); err != nil {
			t.Error(err)
		} else {
			fmt.Printf("%T\n", v)
			if err := pool.ReleaseObj(v); err != nil {
				t.Error(err)
			}
		}
	}
}

输出

=== RUN   TestObjPool
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
*obj_pool.ReusableObj
--- PASS: TestObjPool (0.00s)
PASS

Process finished with exit code 0

其实我们只初始化了10个对象,但是我们使用了11次,并没有报错; 可以利用 buffer channel 可以缓存哪些难以创建可复用的对象;但也要进行性能测试,做出取舍

示例代码请访问:github.com/wenjianzhan…