面试题答案
一键面试确保结构体方法在并发调用时安全性的方法
- 使用互斥锁(Mutex):互斥锁是一种简单有效的同步机制,它可以保证在同一时间只有一个 goroutine 能够访问共享资源。在结构体方法中,通过在访问共享资源前锁定互斥锁,访问完成后解锁互斥锁来确保线程安全。
- 读写锁(RWMutex):如果结构体中的数据大部分时间是被读取,只有偶尔需要写入操作,可以使用读写锁。读写锁允许多个 goroutine 同时进行读操作,但只允许一个 goroutine 进行写操作。当有写操作时,所有读操作都会被阻塞。
代码示例
- 使用互斥锁(Mutex)
package main
import (
"fmt"
"sync"
)
// Counter 结构体
type Counter struct {
count int
mu sync.Mutex
}
// Increment 方法增加计数器的值
func (c *Counter) Increment() {
c.mu.Lock()
c.count++
c.mu.Unlock()
}
// GetCount 方法获取计数器的值
func (c *Counter) GetCount() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.count
}
可以通过以下方式调用:
func main() {
var wg sync.WaitGroup
counter := Counter{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Increment()
}()
}
wg.Wait()
fmt.Println("Final count:", counter.GetCount())
}
- 使用读写锁(RWMutex)
package main
import (
"fmt"
"sync"
)
// Data 结构体
type Data struct {
value int
mu sync.RWMutex
}
// Read 方法读取数据
func (d *Data) Read() int {
d.mu.RLock()
defer d.mu.RUnlock()
return d.value
}
// Write 方法写入数据
func (d *Data) Write(newValue int) {
d.mu.Lock()
d.value = newValue
d.mu.Unlock()
}
调用示例:
func main() {
var wg sync.WaitGroup
data := Data{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
data.Write(i)
}()
}
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Read value:", data.Read())
}()
}
wg.Wait()
}
在上述代码中,Counter
结构体通过 sync.Mutex
确保 Increment
和 GetCount
方法在并发调用时的安全性。Data
结构体通过 sync.RWMutex
确保读操作(Read
方法)和写操作(Write
方法)在并发环境下的安全。写操作使用 Lock
方法,读操作使用 RLock
方法。