长时间来一直以为在读多写少的场景下,读写锁性能必然优于互斥锁,然而情况恰恰相反

不废话了,先上一段测试代码

func main() {

var w = &sync.WaitGroup{}

var num = 50000000

var c = make(chan int, 3000)

var rwmutexTmp = newRwmutex()

w.Add(num)

t1 := time.Now()

for i := 0; i < num; i++ {

c

go func(index int) {

defer w.Done()

_ = rwmutexTmp.get(index)

//fmt.Println(value)

}(i)

}

w.Wait()

t2 := time.Now()

var mutexTmp = newMutex()

w.Add(num)

t3 := time.Now()

for i := 0; i < num; i++ {

c

go func(index int) {

defer w.Done()

t := mutexTmp.get()

_, _ = t[index]

//fmt.Println(ok)

}(i)

}

w.Wait()

t4 := time.Now()

fmt.Println("rwmutex cost:", t2.Sub(t1).String())

fmt.Println("mutex cost:", t4.Sub(t3).String())

}

type rwmutex struct {

mu *sync.RWMutex

ipmap map[int]int

}

type mutex struct {

mu *sync.Mutex

ipmap map[int]int

}

func (t *rwmutex) get(i int) int {

t.mu.RLock()

defer t.mu.RUnlock()

return t.ipmap[i]

}

func (t *mutex) get() map[int]int {

t.mu.Lock()

defer t.mu.Unlock()

return t.ipmap

}

func newRwmutex() *rwmutex {

var t = &rwmutex{}

t.mu = &sync.RWMutex{}

t.ipmap = make(map[int]int, 100)

for i := 0; i < 100; i++ {

t.ipmap[i] = 0

}

return t

}

func newMutex() *mutex {

var t = &mutex{}

t.mu = &sync.Mutex{}

t.ipmap = make(map[int]int, 100)

for i := 0; i < 100; i++ {

t.ipmap[i] = 0

}

return t

}

各加锁5000万次,时间比较如下:

go run test_rwmutex_mutex.go

rwmutex cost: 22.403487195s

mutex cost: 21.636404963s

go run test_rwmutex_mutex.go

rwmutex cost: 22.3359224s

mutex cost: 21.931208658s

在某些场景下,互斥锁要比读写锁更快!!!