Go: 谨慎使用 math/rand 包中的默认随机数函数

比如 rand.Int63
这个函数的 源代码
如下:

func Int63n(n int64) int64 { return globalRand.Int63n(n) }

可以看到它其实是调用了一个全局的 Rand 实例 globalRand
,我们来看一下 globalRand
定义
:

var globalRand = New(&lockedSource{src: NewSource(1).(Source64)})

通过 New
的源码以及 globalRand.Int63n
的源码可以看到关键点是 lockedSource.Int63
方法的定义:

 type lockedSource struct {
     lk  sync.Mutex
     src Source64
 }

 func (r *lockedSource) Int63() (n int64) {
     r.lk.Lock()
     n = r.src.Int63()
     r.lk.Unlock()
     return
 }

通过同样的方法查看其他默认的随机函数可以发现,所有的默认随机函数都共享了一个全局锁,调用这些默认随机函数的时候都会先进行一次获取锁的操作。