go 单例与线程安全

理解

1.需要读同一份数据,使用单例

2.需要读写同一份数据单例+锁达到线程安全

测试代码

package code

import "sync"

/**
 * 使用结构体代替类
 */
type Tool struct {
    values int
}

/**
 * 建立私有变量
 */
var instance *Tool

/**
非线程安全
 * 获取单例对象的方法,引用传递返回
*/
func GetInstance1() *Tool {
    if instance == nil {
        instance = new(Tool)
    }

    return instance
}

/**
线程安全
 * 锁对象
*/
var lock sync.Mutex

/**
需要进行写操作需要考虑线程安全
 * 加锁保证线程安全
 */
func GetInstanceByLock() *Tool {
    lock.Lock()
    defer lock.Unlock()
    if instance == nil {
        instance = new(Tool)
    }

    return instance
}

//直接创建好对象,这样不需要判断为空,同时也是线程安全。唯一的缺点是在导入包的同时会创建该对象,并持续占有在内存中
var instance2 Tool

func GetInstance2() *Tool {
    return &instance2
}

//4.双重检查

/**
* 锁对象
 */
var lock3 sync.Mutex

/**
* 第一次判断不加锁,第二次加锁保证线程安全,一旦对象建立后,获取对象就不用加锁了
 */
func GetInstance3() *Tool {
    if instance == nil {
        lock3.Lock()
        if instance == nil {
            instance = new(Tool)
        }
        lock3.Unlock()
    }
    return instance
}

//5.sync.Once
//通过sync.Once 来确保创建对象的方法只执行一次

var once sync.Once

func GetInstance5() *Tool {
    once.Do(func() {
        instance = new(Tool)

    })
    return instance
}

func ValuesSet(a int) {
    GetInstance5().values = a
}

func ValuesGet() int {
    return GetInstance5().values
}
View Code
原文地址:https://www.cnblogs.com/huay/p/15042879.html