1. package main
    2. import (
    3. "errors"
    4. "fmt"
    5. "sync"
    6. "time"
    7. )
    8. type ReusableObj struct {
    9. }
    10. type ObjPool struct {
    11. bufChan chan *ReusableObj
    12. }
    13. func (this *ObjPool) GetObj(timeout time.Duration) (*ReusableObj, error) {
    14. select {
    15. case ret := <-this.bufChan:
    16. return ret, nil
    17. case <-time.After(timeout):
    18. return nil, errors.New("timeout")
    19. }
    20. }
    21. func (this *ObjPool) ReleaseObj(obj *ReusableObj) error {
    22. select {
    23. case this.bufChan <- obj:
    24. return nil
    25. default:
    26. return errors.New("overflow")
    27. }
    28. }
    29. func NewObjPool(NumOfObj int) *ObjPool {
    30. objPool := ObjPool{bufChan: make(chan *ReusableObj, NumOfObj)}
    31. for i := 0; i < NumOfObj; i++ {
    32. objPool.bufChan <- &ReusableObj{}
    33. }
    34. return &objPool
    35. }
    36. func main() {
    37. pool := NewObjPool(10)
    38. wg := sync.WaitGroup{}
    39. for i := 0; i < 200; i++ {
    40. go func() {
    41. wg.Add(1)
    42. defer wg.Done()
    43. v, err := pool.GetObj(time.Second * 3)
    44. if err != nil {
    45. fmt.Println(err)
    46. return
    47. }
    48. time.Sleep(time.Millisecond * 100)
    49. fmt.Println("do something")
    50. err = pool.ReleaseObj(v)
    51. if err != nil {
    52. fmt.Println(err)
    53. return
    54. }
    55. }()
    56. }
    57. wg.Wait()
    58. fmt.Println("Done!")
    59. }