golang atomic和定时任务的思考
atomic 某写操作在大并发的环境下 有一些差异。下文中 tttt1和 tttt3 是绝对安全的
go
package main
import (
"log"
"runtime"
"sync/atomic"
"time"
)
var (
NowtimeATO atomic.Int64
LastUpdateCfgATO atomic.Int64
UpdateCfgLock atomic.Int32
)
func main() {
log.SetFlags(log.Lmicroseconds)
NowtimeATO.Store(time.Now().Unix())
LastUpdateCfgATO.Store(NowtimeATO.Load())
var count int64 = 0
for {
count++
for i := 0; i < 3000000; i++ {
go tttt3(count)
}
time.Sleep(1 * time.Second)
}
}
func tttt1(x int64) {
NowtimeATO.Store(time.Now().Unix())
if NowtimeATO.Load()-LastUpdateCfgATO.Load() > 0 { //超过N秒
if UpdateCfgLock.CompareAndSwap(0, 1) { //如果是0 那么修改为1 如是0 否则不执行
LastUpdateCfgATO.Store(NowtimeATO.Load())
UpdateCfg(x)
UpdateCfgLock.Store(0)
}
}
time.Sleep(3 * time.Second)
}
func tttt2(x int64) {
NowtimeATO.Store(time.Now().Unix())
if NowtimeATO.Load()-LastUpdateCfgATO.Load() > 0 { //超过N秒
LastUpdateCfgATO.Store(NowtimeATO.Load())
UpdateCfg(x)
}
time.Sleep(3 * time.Second)
}
func tttt3(x int64) {
if time.Now().Unix()-LastUpdateCfgATO.Load() > 0 { //超过N秒
if UpdateCfgLock.CompareAndSwap(0, 1) { //如果是0 那么修改为1 如是0 否则不执行
LastUpdateCfgATO.Store(time.Now().Unix()) //极小概率和前面的不一致
UpdateCfg(x)
UpdateCfgLock.Store(0)
}
}
//time.Sleep(2000 * time.Microsecond)
time.Sleep(3 * time.Second)
}
func UpdateCfg(x int64) {
//log.Println("val:", UpdateCfgLock.Load(), "times:", x)
log.Println("times:", x, "NumGoroutine", runtime.NumGoroutine())
}