golang atomic和定时任务的思考

golang

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())
}

评论