package main
import (
"errors"
"fmt"
"sync"
"time"
)
type ReusableObj struct {
}
type ObjPool struct {
bufChan chan *ReusableObj
}
func (this *ObjPool) GetObj(timeout time.Duration) (*ReusableObj, error) {
select {
case ret := <-this.bufChan:
return ret, nil
case <-time.After(timeout):
return nil, errors.New("timeout")
}
}
func (this *ObjPool) ReleaseObj(obj *ReusableObj) error {
select {
case this.bufChan <- obj:
return nil
default:
return errors.New("overflow")
}
}
func NewObjPool(NumOfObj int) *ObjPool {
objPool := ObjPool{bufChan: make(chan *ReusableObj, NumOfObj)}
for i := 0; i < NumOfObj; i++ {
objPool.bufChan <- &ReusableObj{}
}
return &objPool
}
func main() {
pool := NewObjPool(10)
wg := sync.WaitGroup{}
for i := 0; i < 200; i++ {
go func() {
wg.Add(1)
defer wg.Done()
v, err := pool.GetObj(time.Second * 3)
if err != nil {
fmt.Println(err)
return
}
time.Sleep(time.Millisecond * 100)
fmt.Println("do something")
err = pool.ReleaseObj(v)
if err != nil {
fmt.Println(err)
return
}
}()
}
wg.Wait()
fmt.Println("Done!")
}