go并发-对象池实现
Posted 文大侠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go并发-对象池实现相关的知识,希望对你有一定的参考价值。
实际编程中,常遇到对象池的需求,如数据库连接,网络连接等对象持有。
对象池,简单来说就是维持一个并发访问的池子,需要对象时从池子取,用完了再还回去。在golang中通过维持一个带缓冲channel很容易完成这一功能,天然具有并发访问安全性。
简单实现如下
type ConnectPool struct {
connects chan int
count int
}
func NewConnectPool(count int) *ConnectPool {
p := &ConnectPool{make(chan int, count), count}
// 初始化放入一批对象
for i := 0; i < count; i++ {
p.connects <- i
}
return p
}
func (p *ConnectPool) Get() (int, error) {
select {
case id := <-p.connects:
return id, nil
case <-time.After(time.Millisecond): // 增加超时控制
fmt.Println("Get timeout!")
return 0, errors.New("Get timeout!")
}
}
func (p *ConnectPool) Release(id int) {
select {
case p.connects <- id: // 还回去
default: // 放不下时报错
fmt.Println("Overflow")
}
}
func TestConnPool(t *testing.T) {
p := NewConnectPool(5)
var wg sync.WaitGroup
for i := 0; i < 20; i++ {
wg.Add(1)
go func() {
var id int
var err error
if id, err = p.Get(); err!=nil {
return
}
fmt.Printf("Get connect id %v\\n", id)
time.Sleep(time.Duration(rand.Intn(10000)))
p.Release(id)
wg.Done()
}()
}
wg.Wait()
}
注意go中自带的sync.Pool严格来说应该叫sync.Cache,它保存的对象有可能被自动回收,显然是不能拿来保存数据库连接等持久化对象的。
原创,转载请注明来自
以上是关于go并发-对象池实现的主要内容,如果未能解决你的问题,请参考以下文章