【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{} 任意类型。
不是说用对象池,一定会带来好的性能。 要分情况。