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并发-对象池实现的主要内容,如果未能解决你的问题,请参考以下文章

go并发-对象池实现

go并发-对象池实现

Go的CSP并发模型实现:M, P, G

Go语言之并发示例-Pool

深入浅出Golang的协程池设计

[Go] golang缓冲通道实现资源池