You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

bucket_pool.go 1.5 kB

10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
10 months ago
8 months ago
10 months ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package sync2
  2. import "sync"
  3. type BucketPool[T any] struct {
  4. empty []T
  5. filled []T
  6. emptyCond *sync.Cond
  7. filledCond *sync.Cond
  8. closed bool
  9. }
  10. func NewBucketPool[T any]() *BucketPool[T] {
  11. return &BucketPool[T]{
  12. emptyCond: sync.NewCond(&sync.Mutex{}),
  13. filledCond: sync.NewCond(&sync.Mutex{}),
  14. }
  15. }
  16. func (p *BucketPool[T]) GetEmpty() (T, bool) {
  17. p.emptyCond.L.Lock()
  18. defer p.emptyCond.L.Unlock()
  19. if p.closed {
  20. var t T
  21. return t, false
  22. }
  23. if len(p.empty) == 0 {
  24. p.emptyCond.Wait()
  25. }
  26. if len(p.empty) == 0 {
  27. var t T
  28. return t, false
  29. }
  30. t := p.empty[0]
  31. p.empty = p.empty[1:]
  32. return t, true
  33. }
  34. func (p *BucketPool[T]) PutEmpty(t T) {
  35. p.emptyCond.L.Lock()
  36. defer p.emptyCond.L.Unlock()
  37. p.empty = append(p.empty, t)
  38. p.emptyCond.Signal()
  39. }
  40. func (p *BucketPool[T]) GetFilled() (T, bool) {
  41. p.filledCond.L.Lock()
  42. defer p.filledCond.L.Unlock()
  43. if len(p.filled) == 0 {
  44. if p.closed {
  45. var t T
  46. return t, false
  47. }
  48. p.filledCond.Wait()
  49. }
  50. if len(p.filled) == 0 {
  51. var t T
  52. return t, false
  53. }
  54. t := p.filled[0]
  55. p.filled = p.filled[1:]
  56. return t, true
  57. }
  58. func (p *BucketPool[T]) PutFilled(t T) {
  59. p.filledCond.L.Lock()
  60. defer p.filledCond.L.Unlock()
  61. p.filled = append(p.filled, t)
  62. p.filledCond.Signal()
  63. }
  64. func (p *BucketPool[T]) Close() {
  65. // 在两个锁中分别关闭,防止变量可见性问题
  66. p.emptyCond.L.Lock()
  67. p.closed = true
  68. p.emptyCond.L.Unlock()
  69. p.filledCond.L.Lock()
  70. p.closed = true
  71. p.filledCond.L.Unlock()
  72. p.emptyCond.Broadcast()
  73. p.filledCond.Broadcast()
  74. }