github.com/rolandhe/saber@v0.0.4/gocc/countdownlatch.go (about) 1 // Golang concurrent tools like java juc. 2 // 3 // Copyright 2023 The saber Authors. All rights reserved. 4 5 // Package gocc, 提供类似java juc的库能力。包括: 6 // 7 // Cond with timeout,相比于标准库Cond,它最典型的特点是支持timeout 8 // 9 // Future,类似java的Future,提交到任务执行器的任务可以被异步执行,调用者持有Future来获取异步执行的结果或者取消任务 10 // 11 // FutureGroup, 包含多个Future,可以在FutureGroup上等待所有的Future任务都执行完成,也可以取消任务,相比于在多个Future上一个个轮询,调用更加简单 12 // 13 // BlockingQueue, 支持并发调用的、并行安全的队列,强制有界 14 // 15 // Executor, 用于异步执行任务的执行器,强制指定并发数。要执行的任务提交给Executor后马上返回Future,调用者持有Future来获取最终结果,Executor内执行完成任务或者发现任务取消后会修改Future的内部状态 16 // 17 // Semaphore,信号量 18 // 19 // CountdownLatch, 倒计数 20 package gocc 21 22 import ( 23 "sync/atomic" 24 "time" 25 ) 26 27 // NewCountdownLatch 构建总量为count的倒计数,相比于WaitGroup, CountdownLatch提供的能力更丰富 28 // 29 // count 数据总量 30 func NewCountdownLatch(count int64) *CountdownLatch { 31 if count < 0 { 32 panic("invalid tokenCount value") 33 } 34 p := &CountdownLatch{ 35 tokenCount: &atomic.Int64{}, 36 notifier: make(chan struct{}), 37 } 38 p.tokenCount.Add(count) 39 return p 40 } 41 42 // CountdownLatch ,类似java的CountdownLatch,实现倒计数功能,支持wait timeout 43 type CountdownLatch struct { 44 tokenCount *atomic.Int64 45 notifier chan struct{} 46 } 47 48 // Down 倒计数减一 49 func (dw *CountdownLatch) Down() int64 { 50 if dw.tokenCount.Load() <= 0 { 51 return 0 52 } 53 v := dw.tokenCount.Add(-1) 54 if v == 0 { 55 close(dw.notifier) 56 } 57 if v < 0 { 58 v = 0 59 } 60 return v 61 } 62 63 // TryWait 尝试等待, 如果已经倒计数到0,则返回true,否则立即返回false 64 func (dw *CountdownLatch) TryWait() bool { 65 select { 66 case <-dw.notifier: 67 return true 68 default: 69 return false 70 } 71 } 72 73 // Wait 等待,直到倒计数到0 74 func (dw *CountdownLatch) Wait() { 75 <-dw.notifier 76 } 77 78 // WaitTimeout 带超时的等待倒计数到0,如果超时内倒计数到0,返回true,否则返回false 79 func (dw *CountdownLatch) WaitTimeout(timeout time.Duration) bool { 80 select { 81 case <-dw.notifier: 82 return true 83 case <-time.After(timeout): 84 return false 85 } 86 }