Golang Map并发处理机制(sync.Map)

Go语言中的Map在并发情况下,只读是线程安全的,同时读写线程不安全。

示例:

package main

import (
	"fmt"
)
var m = make(map[int]int)
func main() {
	//写入操作
	i:=0
	go func() {
		for{
			i++
			m[1]=i
		}

	}()
	//读操作
	go func() {
		for{
			fmt.Println(m[1])
		}

	}()
	//无限循环,让并发程序在后台运行
	for {
		;
	}
}

从以上示例可以看出,不断地对map进行读和写,会出现错误。主要原因是对map进行读和写发生了竞态问题。map内部会对这种并发操作进行检查并提前发现。

如果确实需要对map进行并发读写操作,可以采用加锁机制、channel同步机制,但这样性能并不高。

Go语言在1.9版本中提供了一种效率较高的并发安全的sync.Map。sync.Map结构如下:

 The zero Map is empty and ready for use. A Map must not be copied after first use.
type Map struct {
	mu Mutex
	misses int
}

// Load returns the value stored in the map for a key, or nil if no
// value is present.
// The ok result indicates whether value was found in the map.
func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
	
}

// Store sets the value for a key.
func (m *Map) Store(key, value interface{}) {
	
}
// LoadOrStore returns the existing value for the key if present.
// Otherwise, it stores and returns the given value.
// The loaded result is true if the value was loaded, false if stored.
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
	
}

// Delete deletes the value for a key.
func (m *Map) Delete(key interface{}) {
	
}


// Range calls f sequentially for each key and value present in the map.
// If f returns false, range stops the iteration.
//
// Range does not necessarily correspond to any consistent snapshot of the Map's
// contents: no key will be visited more than once, but if the value for any key
// is stored or deleted concurrently, Range may reflect any mapping for that key
// from any point during the Range call.
//
// Range may be O(N) with the number of elements in the map even if f returns
// false after a constant number of calls.
func (m *Map) Range(f func(key, value interface{}) bool) {
	
}

func (m *Map) missLocked() {
	
}

func (m *Map) dirtyLocked() {
	
}

其实,sync.Map内部还是进行了加锁机制,不过进行了一定的优化。

sync.Map使用示例:

package main

import (
	"fmt"
	"sync"
	"time"
)

var m1 sync.Map

func main() {
	i := 0
	go func() {
		for {
			i++
			m1.Store(1, i)
			time.Sleep(1000)
		}
	}()
	go func() {
		for{
			time.Sleep(1000)
			fmt.Println(m1.Load(1))
		}

	}()
	for {
		;
	}
}

成功运行效果如下:

了解更多Go语言知识https://study.163.com/course/introduction/1210620804.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值