互斥锁 vs 读写锁性能对比
package main
import (
"fmt"
"strings"
"sync"
"time"
)
type DataStore struct {
data map[int]string
mu sync.Mutex
rwmu sync.RWMutex
}
func NewDataStore() *DataStore {
return &DataStore{
data: make(map[int]string),
}
}
func (ds *DataStore) ReadWithMutex(key int) (string, bool) {
ds.mu.Lock()
defer ds.mu.Unlock()
time.Sleep(1 * time.Millisecond)
value, exists := ds.data[key]
return value, exists
}
func (ds *DataStore) WriteWithMutex(key int, value string) {
ds.mu.Lock()
defer ds.mu.Unlock()
time.Sleep(5 * time.Millisecond)
ds.data[key] = value
}
func (ds *DataStore) ReadWithRWMutex(key int) (string, bool) {
ds.rwmu.RLock()
defer ds.rwmu.RUnlock()
time.Sleep(1 * time.Millisecond)
value, exists := ds.data[key]
return value, exists
}
func (ds *DataStore) WriteWithRWMutex(key int, value string) {
ds.rwmu.Lock()
defer ds.rwmu.Unlock()
time.Sleep(5 * time.Millisecond)
ds.data[key] = value
}
func benchmark(name string, readFunc func(), writeFunc func(), readers, writers int) {
var wg sync.WaitGroup
start := time.Now()
for i := 0; i < readers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 100; j++ {
readFunc()
}
}()
}
for i := 0; i < writers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 20; j++ {
writeFunc()
}
}()
}
wg.Wait()
elapsed := time.Since(start)
fmt.Printf("%s:\n", name)
fmt.Printf(" 读者数: %d, 写着数: %d\n", readers, writers)
fmt.Printf(" 耗时: %v\n", elapsed)
fmt.Printf(" 总操作数: %d\n", readers*100+writers*20)
fmt.Println()
}
func main() {
ds := NewDataStore()
fmt.Println("性能对比测试(读多写少场景):")
fmt.Println(strings.Repeat("=", 50))
benchmark("互斥锁",
func() { ds.ReadWithMutex(1) },
func() { ds.WriteWithMutex(1, "value") },
100, 5)
benchmark("读写锁",
func() { ds.ReadWithRWMutex(1) },
func() { ds.WriteWithRWMutex(1, "value") },
100, 5)
fmt.Println("性能对比测试(读写平衡场景):")
fmt.Println(strings.Repeat("=", 50))
benchmark("互斥锁",
func() { ds.ReadWithMutex(2) },
func() { ds.WriteWithMutex(2, "value") },
50, 50)
benchmark("读写锁",
func() { ds.ReadWithRWMutex(2) },
func() { ds.WriteWithRWMutex(2, "value") },
50, 50)
fmt.Println("性能对比测试(写多读少场景):")
fmt.Println(strings.Repeat("=", 50))
benchmark("互斥锁",
func() { ds.ReadWithMutex(3) },
func() { ds.WriteWithMutex(3, "value") },
10, 90)
benchmark("读写锁",
func() { ds.ReadWithRWMutex(3) },
func() { ds.WriteWithRWMutex(3, "value") },
10, 90)
}
缓存系统
package main
import (
"fmt"
"sync"
"time"
)
type Cache struct {
data map[string]interface{}
rwmu sync.RWMutex
stats CacheStats
statsMu sync.Mutex
}
type CacheStats struct {
hits int
misses int
evicts int
}
func NewCache() *Cache {
return &Cache{
data: make(map[string]interface{}),
stats: CacheStats{
hits: 0,
misses: 0,
evicts: 0,
},
}
}
func (c *Cache) Get(key string) (interface{}, bool) {
c.rwmu.RLock()
value, exists := c.data[key]
c.rwmu.RUnlock()
c.statsMu.Lock()
if exists {
c.stats.hits++
fmt.Printf("缓存命中: %s\n", key)
} else {
c.stats.misses++
fmt.Printf("缓存未命中: %s\n", key)
}
c.statsMu.Unlock()
return value, exists
}
func (c *Cache) Set(key string, value interface{}) {
c.rwmu.Lock()
defer c.rwmu.Unlock()
time.Sleep(15 * time.Millisecond)
c.data[key] = value
fmt.Printf("设置缓存: %s = %v\n", key, value)
}
func (c *Cache) Delete(key string) bool {
c.rwmu.Lock()
defer c.rwmu.Unlock()
_, exists := c.data[key]
if exists {
delete(c.data, key)
c.statsMu.Lock()
c.stats.evicts++
c.statsMu.Unlock()
fmt.Printf("删除缓存: %s\n", key)
}
return exists
}
func (c *Cache) GetStats() CacheStats {
c.statsMu.Lock()
defer c.statsMu.Unlock()
return c.stats
}
func (c *Cache) Clear() {
c.rwmu.Lock()
defer c.rwmu.Unlock()
c.data = make(map[string]interface{})
c.statsMu.Lock()
c.stats.evicts = 0
c.statsMu.Unlock()
fmt.Println("缓存已清空")
}
func main() {
cache := NewCache()
var wg sync.WaitGroup
for i := 1; i <= 15; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 0; j < 10; j++ {
key := fmt.Sprintf("key%d", (id+j)%10)
cache.Get(key)
time.Sleep(time.Millisecond * 5)
}
}(i)
}
for i := 1; i <= 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 0; j < 3; j++ {
key := fmt.Sprintf("key%d", id*10+j)
cache.Set(key, fmt.Sprintf("value%d", id*100+j))
time.Sleep(time.Millisecond * 30)
}
}(i)
}
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(300 * time.Millisecond)
cache.Clear()
}()
wg.Wait()
stats := cache.GetStats()
fmt.Printf("\n缓存统计:\n")
fmt.Printf("命中次数: %d\n", stats.hits)
fmt.Printf("未命中次数: %d\n", stats.misses)
fmt.Printf("驱逐次数: %d\n", stats.evicts)
}
死锁预防与检测
package main
import (
"fmt"
"sync"
"time"
)
func deadlockExample() {
var mu1, mu2 sync.Mutex
go func() {
mu1.Lock()
fmt.Println("goroutine1 获取 mu1")
time.Sleep(100 * time.Millisecond)
mu2.Lock()
fmt.Println("goroutine1 获取 mu2")
mu2.Unlock()
mu1.Unlock()
}()
go func() {
mu2.Lock()
fmt.Println("goroutine2 获取 mu2")
time.Sleep(100 * time.Millisecond)
mu1.Lock()
fmt.Println("goroutine2 获取 mu1")
mu1.Unlock()
mu2.Unlock()
}()
time.Sleep(2 * time.Second)
fmt.Println("程序结束(可能已经死锁)")
}
func correctExample() {
var mu1, mu2 sync.Mutex
go func() {
mu1.Lock()
fmt.Println("goroutine1 获取 mu1")
time.Sleep(100 * time.Millisecond)
mu2.Lock()
fmt.Println("goroutine1 获取 mu2")
mu2.Unlock()
mu1.Unlock()
}()
go func() {
mu1.Lock()
fmt.Println("goroutine2 获取 mu1")
time.Sleep(100 * time.Millisecond)
mu2.Lock()
fmt.Println("goroutine2 获取 mu2")
mu2.Unlock()
mu1.Unlock()
}()
time.Sleep(2 * time.Second)
fmt.Println("程序正常结束")
}
func deferExample() {
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
fmt.Println("临界区操作")
}
func tryLockExample() {
var mu sync.Mutex
if mu.TryLock() {
defer mu.Unlock()
fmt.Println("成功获取锁")
} else {
fmt.Println("锁已被占用,执行其他操作")
}
}
func main() {
fmt.Println("=== 死锁示例 ===")
go deadlockExample()
time.Sleep(3 * time.Second)
fmt.Println("\n=== 正确示例 ===")
correctExample()
fmt.Println("\n=== defer 示例 ===")
deferExample()
fmt.Println("\n=== TryLock 示例 ===")
tryLockExample()
}
线程安全的队列
package main
import (
"fmt"
"sync"
"time"
)
type ThreadSafeQueue struct {
items []interface{}
mu sync.RWMutex
cond *sync.Cond
}
func NewThreadSafeQueue() *ThreadSafeQueue {
q := &ThreadSafeQueue{
items: make([]interface{}, 0),
}
q.cond = sync.NewCond(&q.mu)
return q
}
func (q *ThreadSafeQueue) Enqueue(item interface{}) {
q.mu.Lock()
defer q.mu.Unlock()
q.items = append(q.items, item)
fmt.Printf("入队: %v, 队列长度: %d\n", item, len(q.items))
q.cond.Signal()
}
func (q *ThreadSafeQueue) Dequeue() interface{} {
q.mu.Lock()
defer q.mu.Unlock()
for len(q.items) == 0 {
fmt.Println("队列为空,等待中...")
q.cond.Wait()
}
item := q.items[0]
q.items = q.items[1:]
fmt.Printf("出队: %v, 队列长度: %d\n", item, len(q.items))
return item
}
func (q *ThreadSafeQueue) TryDequeue() (interface{}, bool) {
q.mu.Lock()
defer q.mu.Unlock()
if len(q.items) == 0 {
return nil, false
}
item := q.items[0]
q.items = q.items[1:]
fmt.Printf("尝试出队成功: %v\n", item)
return item, true
}
func (q *ThreadSafeQueue) Peek() (interface{}, bool) {
q.mu.RLock()
defer q.mu.RUnlock()
if len(q.items) == 0 {
return nil, false
}
return q.items[0], true
}
func (q *ThreadSafeQueue) Size() int {
q.mu.RLock()
defer q.mu.RUnlock()
return len(q.items)
}
func main() {
queue := NewThreadSafeQueue()
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 1; j <= 5; j++ {
item := fmt.Sprintf("生产者%d-项目%d", id, j)
queue.Enqueue(item)
time.Sleep(time.Millisecond * 50 * time.Duration(id))
}
}(i)
}
for i := 1; i <= 2; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 1; j <= 8; j++ {
item := queue.Dequeue()
fmt.Printf("消费者%d 消费: %v\n", id, item)
time.Sleep(time.Millisecond * 80)
}
}(i)
}
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
if item, ok := queue.TryDequeue(); ok {
fmt.Printf("非阻塞消费者 消费: %v\n", item)
} else {
fmt.Println("非阻塞消费者: 队列为空")
}
time.Sleep(time.Millisecond * 100)
}
}()
wg.Wait()
fmt.Printf("\n最终队列大小: %d\n", queue.Size())
}