golang atomic和定时任务的思考

atomic 某写操作在大并发的环境下 有一些差异。下文中 tttt1和 tttt3 是绝对安全的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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())
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计