zoukankan      html  css  js  c++  java
  • go接收者和锁注意事项

    go接收者和锁注意事项

    • 如果需要修改对象中的值,建议使用指针接收者。如果不需要修改对象中的值,建议使用值接收者。

      • 代码

        package main
        
        import (
        	"fmt"
        )
        
        type Student struct {
        	Name string
        	Age  int
        }
        
        func (s Student) UpdateName(name string) {
        	s.Name = name
        }
        
        func (s *Student) UpdateAge(age int) {
        	s.Age = age
        }
        
        func main() {
        	s := Student{Name: "jom", Age: 20}
        	fmt.Println(s)
        	s.UpdateName("tim")
        	fmt.Println(s)
        	s.UpdateAge(22)
        	fmt.Println(s)
        }
        
        
      • 输出

        {jom 20}
        {jom 20}
        {jom 22}
        
      • 从输出可以分析出来,当为值接收者的时候,也就是 (s Student) ,是不会修改对象值的。当为指针接收者的时候,也就是(s *Student) ,是会修改对象值的。从代码上看,这是因为无论何时调用UpdateName函数,s都会是一份值拷贝,无论怎么修改UpdateName函数中s的值,都不会对main函数中的s值有任何的影响。而UpdateAge函数,s是指针,也就是在调用的时候指针接收者s的地址和main函数中s的地址是一致的,使用指针接收者进行修改,会对main函数中的s的值有影响。

    • 锁的拷贝是建立新的锁

      • 代码
      package main
      
      import (
      	"fmt"
      	"sync"
      	"time"
      )
      
      type Class struct {
      	sync.Mutex
      	Student map[string]int
      }
      
      func (c Class) inc(key string) {
      	c.Lock()
      	defer c.Unlock()
      	c.Student[key]++
      }
      
      func main() {
      	c := Class{Student: map[string]int{"aa": 0, "bb": 0}}
      	do := func(key string, frequency int) {
      		for i := 0; i < frequency; i++ {
      			c.inc(key)
      		}
      	}
      	go do("aa", 1000)
      	go do("aa", 1000)
      
      	time.Sleep(10 * time.Second)
      	fmt.Println(c.Student)
      }
      
      • 输出
      fatal error: concurrent map writes
      
      • 从结果看来是map的读写冲突了。从代码上看,这是因为我们调用c.inc函数的时候,对main函数中的c进行了拷贝,而c中字段Mutex 由于是值类型,在拷贝的时候也拷贝了一份,而c中的map由于是引用类型,依然是指向同一个map。这样就会造成两或两个以上的协程同时修改map中的值时,对map的互斥失效,从而导致的写冲突。
  • 相关阅读:
    接口测试01
    mysql主从
    linux下配置JDK
    linux常用命令
    mysql基本语句
    线程与进程
    loadrunner函数
    设计模式-模板方法模式
    设计原则-CRP合成复用原则
    设计原则-LOD迪米特法则
  • 原文地址:https://www.cnblogs.com/MyUniverse/p/15112359.html
Copyright © 2011-2022 走看看