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!")
    }
    

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

  • 相关阅读:
    队列
    栈的链式存储
    单例和多例设计模式
    顺序栈的基本操作
    串的模式匹配
    线性表的链式存储结构
    倒置顺序表
    回文序列
    go语言系列-从运算符到函数
    go语言系列-从零到数据类型
  • 原文地址:https://www.cnblogs.com/wuyongqiang/p/12143728.html
Copyright © 2011-2022 走看看