单例模式(Go&Java)

单例模式

单例模式(Singleton)是一种非常简单且容易理解的设计模式。顾名思义,单例即单一的实例,确切地讲就是指在某个系统中只存在一个实例,同时提供集中、统一的访问接口,以使系统行为保持协调一致。singleton一词在逻辑学中指“有且仅有一个元素的集合”,这非常恰当地概括了单例的概念,也就是“一个类仅有一个实例”。

饿汉模式

Java版

“private”关键字确保太阳实例的私有性、不可见性和不可访问性;而“static”关键字确保太阳的静态性,将太阳放入内存里的静态区,在类加载的时候就初始化了,它与类同在,也就是说它是与类同时期且早于内存堆中的对象实例化的,该实例在内存中永生,内存垃圾收集器(Garbage Collector,GC)也不会对其进行回收;“final”关键字则确保这个太阳是常量、恒量,它是一颗终极的恒星,引用一旦被赋值就不能再修改;最后,“new”关键字初始化太阳类的静态实例,并赋予静态常量sun。这就是“饿汉模式”(eager initialization),即在初始阶段就主动进行实例化,并时刻保持一种渴求的状态,无论此单例是否有人使用

public class Sun {
    private static final Sun sun = new Sun();
    private Sun(){
        //构造方法私有
    }
    public static Sun getInstance(){
        return sun;
    }

}

Go版

singleton 包在被导入时会自动初始化 instance 实例,使用时通过调用 singleton.GetSingleton () 函数即可获得 singleton 这个结构体的单例对象。需要注意的是,尽管饿汉式实现单例模式的方式简单,但大多数情况下并不推荐。因为如果单例实例化时初始化内容过多,会造成程序加载用时较长。

package singleton
type singleton struct{}
var instance = &singleton{}
func GetSingleton() *singleton {
    return instance
}

懒汉模式

Java版

public class Sun {
    private volatile static Sun sun;
    
    private Sun(){}
    
    public static Sun getInstance(){
        if (sun==null){
            synchronized (Sun.class){
                if (sun==null){
                    sun = new Sun();
                }
            }
        }
        return sun;
    }
}

Go

在Go语言中,我们有两种饿汉模式的实现方法,一种是模仿Java中的写法

还有一种我们可以使用Go中sync包中的Once

Once 是一个结构体,在执行 Do 方法的内部通过 atomic 操作和加锁机制来保证并发安全,且 once.Do 能够保证多个 goroutine 同时执行时 &singleton {} 只被创建一次。

package singleton

import "sync"

type singleton2 struct{}

var instance2 *singleton2
var mu sync.Mutex

func GetSingleton2() *singleton2 {
    if instance2 == nil {
        mu.Lock()
        defer mu.Unlock()
        if instance2 == nil {
            instance2 = &singleton2{}
        }
    }
    return instance2
}
package singleton

import "sync"

type singleton3 struct{}

var instance3 *singleton3
var once sync.Once

func GetSingleton3() *singleton3 {
    once.Do(func() {
        instance3 = &singleton3{}
    })
    return instance3;
}

相比“懒汉模式”,其实在大多数情况下我们通常会更多地使用“饿汉模式”,原因在于这个单例迟早是要被实例化占用内存的,延迟懒加载的意义并不大,加锁解锁反而是一种资源浪费,同步更是会降低CPU的利用率,使用不当的话反而会带来不必要的风险

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值