【Duke】对象池 031 - PingPongGooo/GoFoundation GitHub Wiki

使用buffered channel 实现对象池

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("time out")
	}
}

func (p *ObjPool) ReleseObj(obj *ReusableObj) error {

	select {
	case p.bufChan<-obj:
		return nil
	default:
		return  errors.New("overflow")
	}
}

package obj_pool

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

func TestObjPool(t *testing.T) {
	pool:= NewObjPool(10)

	//if err:=pool.ReleseObj(&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.ReleseObj(v); err != nil {
				t.Error(err)
			}
		}
	}
	fmt.Println("Done")
}

// 开发中建议使用不同的池,缓存不同的对象。 尽量不要缓存 interface{} 任意类型。

不是说用对象池,一定会带来好的性能。 要分情况。