go语言锁机制,map嵌套使用

1.单例模式误区

Go语言无法完美支持单例模式

现在我们是在并发的情况下去调用的 GetInstance函数,现在恰好第一个goroutine执行到m = &Manager {}这句话之前,第二个goroutine也来获取实例了,第二个goroutine去判断m是不是nil,因为m = &Manager{}还没有来得及执行,所以m肯定是nil,现在出现的问题就是if中的语句可能会执行两遍!

代码做了简单的修改了,引入了锁的机制,在GetInstance函数中,每次调用我们都会上一把锁,保证只有一个goroutine执行它,这个时候并发的问题就解决了。不过现在不管什么情况下都会上一把锁,而且加锁的代价是很大的,有没有办法继续对我们的代码进行进一步的优化呢? 熟悉java的同学可能早就想到了双重的概念,没错,在go中我们也可以使用双重锁机制来提高效率。

 

 

就是我们的sync.Once,它有一个Do方法,在它中的函数go会只保证仅仅调用一次!再次修改我们的代码,

2.对于原有程序优化

但是运行后程序还是出问题map读写出问题并发导致冲突

扫描二维码关注公众号,回复: 11092114 查看本文章

解决方法

锁是必须加的map读写,对于多个IO某一个在读序列号并存储另一个IO在写入序列号会导致并发map

 

3.思考对于map使用锁还是sync.Map来处理

 

 

 

Sync.Map开箱取值为接口—使用接口断言来取值复杂性提高,同时对json支持不友好

 

 

对于加锁和结构体对象选择--------选择结构体对象来访问而不选择加锁

对于sync.Map到底使用不使用?

不推荐使用sync.Map那么如何使用map并安全并发…………………结构体包裹锁与map

4.合理的使用结构体map对象防止并发问题,最好不要单独使用map全局变量

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.go语言三层map嵌套处理逻辑

package main
import (
  
"fmt"
   "strings"
   "time"

)
var channel chan string
var mqttmsgstationmap map[string]map[string]map[string]string //三层嵌套.....
func main() {
  
mqttmsgstationmap = make(map[string]map[string]map[string]string)//字典必须初始化
  
channel = make(chan string, 100)//缓存channel
  
channel <- "11111" + "|" + "@@@" + "|" + "++++"+ "|" +"!!!!"
  
channel <- "11111" + "|" + "@@@" + "|" + "1111"+ "|" +"!!!!"
  
channel <- "22222" + "|" + "^^^" + "|" + "++++"+ "|" +"!!!!"
  
channel <- "22222" + "|" + "***" + "|" + "1111"+ "|" +"!!!!"
  
channel <- "33333" + "|" + "$$$" + "|" + "++++"+ "|" +"!!!!"
  
channel <- "44444" + "|" + "###" + "|" + "1111"+ "|" +"!!!!"
  
go test()
  
time.Sleep(time.Second)
  
fmt.Println(mqttmsgstationmap)
  
for ; ; {
     
time.Sleep(time.Second)
   }
}

func test() {
  
for {
     
select {
     
case msg := <-channel:
        
tempmsg := strings.Split(msg, "|")
        
if len(tempmsg) == 4 {
           
tmpMap := mqttmsgstationmap[tempmsg[0]] //
           
fmt.Printf("%p\n", &tmpMap)
           
if tmpMap == nil {
              
tmpMap = make(map[string]map[string]string)
              
atomm:=mqttmsgstationmap[tempmsg[0]][tempmsg[1]]
              
if  atomm==nil{
                 
atomm=make(map[string]string)
                 
atomm[tempmsg[2]]=tempmsg[3]
                 
tmpMap [tempmsg[1]] = atomm
              
}
            }
else{//二层
              
atomm:=mqttmsgstationmap[tempmsg[0]][tempmsg[1]]
              
if  atomm==nil{
                 
atomm=make(map[string]string)
                 
atomm[tempmsg[2]]=tempmsg[3]
                 
tmpMap [tempmsg[1]] = atomm
              
}else{
                 
atomm[tempmsg[2]]=tempmsg[3]
                 
tmpMap [tempmsg[1]] = atomm
              
}
            }
           
mqttmsgstationmap[tempmsg[0]] = tmpMap//存入一组map释放空间
        
}
      }
   }
}

 

 

 

 

 

Python下多层字典嵌套:

 

New_list = [['key1', 'value1', 'ss','11'], ['key2', 'value2', 'pp','22'], ['key3', 'value3', 'vv','33']]
# 那么对于三维列表可以这样来分离
ss={}
for x in New_list:
   
if x[0] not in ss:
     
ss[x[0]]={}#分配空间
   
if x[1not in ss[x[0]]:
       
ss[x[0]][x[1]]={}
    ss[x[
0]][x[1]][x[2]]=x[3]

print(ss)

 

 

 

 

 

 

 

 

代码逻辑更加清晰

6.系统资源竞争工具的使用

go run -race XXX.go

 

发布了67 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42544051/article/details/102928661