zoukankan      html  css  js  c++  java
  • Go对象池

    对象池是经常会用到的一个功能,使用 buffer 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) // 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) ReleaseObj(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)
    	// 测试 overflow
    	//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
    ", v)
    			if err := pool.ReleaseObj(v); err != nil {
    				t.Error(err)
    			}
    		}
    	}
    	fmt.Println("Done!")
    }
    

    对象池适用于复杂难于创建的对象,对于简单容易创建的对象不适用。

  • 相关阅读:
    bzoj1027
    bzoj1069
    poj2079
    poj2187
    bzoj2281
    bzoj2285
    bzoj1558
    bzoj1822
    bzoj1559
    bzoj1570
  • 原文地址:https://www.cnblogs.com/wuyongqiang/p/12143728.html
Copyright © 2011-2022 走看看