GO语言:线程安全map sync.map

本文探讨了在Go项目中遇到的并发map崩溃问题,以及如何通过引入sync.Map来解决这个问题。sync.Map提供了一种线程安全的方式来在多协程环境中操作map,减少了锁的争用。通过分析sync.Map的源码,可以看出其内部实现了精细的锁策略,提高了并发性能。使用sync.Map相比传统加锁方法,能更有效地避免竞态条件并提高效率。
摘要由CSDN通过智能技术生成
前言

前一段项目启动一段后爆了个map崩溃的异常
原因是多协程操作了一个map 太过频繁
有几率会导致map崩溃
一开始的解决方法是加读写锁
后来发现效果不是太好
于是使用了sync.map

var m  sync.Map //线程安全map
	//数据存入
	m.Store("index1",1000.00)
	//数据取出
	t ,bool := m.Load("index1")
	if bool{
		fmt.Println(t)
	}
	//类型转换
	tmp,bool := t.(float64)
	if bool{
		fmt.Println(tmp)
	}
 	//删除
	 m.Delete("index1")
源码
// Store sets the value for a key.
func (m *Map) Store(key, value interface{}) {
	read, _ := m.read.Load().(readOnly)
	if e, ok := read.m[key]; ok && e.tryStore(&value) {
		return
	}

	m.mu.Lock()
	read, _ = m.read.Load().(readOnly)
	if e, ok := read.m[key]; ok {
		if e.unexpungeLocked() {
			// The entry was previously expunged, which implies that there is a
			// non-nil dirty map and this entry is not in it.
			m.dirty[key] = e
		}
		e.storeLocked(&value)
	} else if e, ok := m.dirty[key]; ok {
		e.storeLocked(&value)
	} else {
		if !read.amended {
			// We're adding the first new key to the dirty map.
			// Make sure it is allocated and mark the read-only map as incomplete.
			m.dirtyLocked()
			m.read.Store(readOnly{m: read.m, amended: true})
		}
		m.dirty[key] = newEntry(value)
	}
	m.mu.Unlock()
}
可以看出来 Store方法使用了线程锁

use of a Map may significantly reduce lock
contention compared to a Go map paired with a separate Mutex or RWMutex.
看源码时 看到了这句话
对常规map使用锁的话,使用sync.map可以显着减少锁争用
那使用起来应该会比自己手动加锁好一些

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值