面试题答案
一键面试适用场景
读写锁适合于读操作远多于写操作的场景。在这种场景下,多个读操作可以同时进行而不会互相影响,而写操作会独占资源,以确保数据的一致性。例如在缓存系统中,大量的请求可能是读取缓存数据,只有偶尔会更新缓存,这种情况下读写锁就很适用。
示例代码
package main
import (
"fmt"
"sync"
"time"
)
var (
counter int
rwMutex sync.RWMutex
)
func reader(id int, wg *sync.WaitGroup) {
defer wg.Done()
rwMutex.RLock()
fmt.Printf("Reader %d reading, counter = %d\n", id, counter)
rwMutex.RUnlock()
}
func writer(id int, wg *sync.WaitGroup) {
defer wg.Done()
rwMutex.Lock()
counter++
fmt.Printf("Writer %d writing, counter = %d\n", id, counter)
rwMutex.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go reader(i, &wg)
}
for i := 0; i < 2; i++ {
wg.Add(1)
go writer(i, &wg)
}
time.Sleep(2 * time.Second)
wg.Wait()
}
在上述代码中,我们定义了一个共享变量counter
和一个读写锁rwMutex
。reader
函数使用读锁(RLock
)来读取counter
的值,多个reader
可以同时执行读操作。writer
函数使用写锁(Lock
)来更新counter
的值,在写操作时会独占资源,防止其他读或写操作同时进行。main
函数启动多个读和写的goroutine,并使用sync.WaitGroup
来等待所有goroutine完成。