首页 > 其他分享 >Golang与设计模式

Golang与设计模式

时间:2024-06-18 17:36:52浏览次数:21  
标签:singleton Java Singleton Golang instance 单例 设计模式

单例模式

因为之前研究Java比较多,所以当我试着使用go来实现一些设计模式的时候,首先想到的就是照搬Java中的思路,后面对go了解加深之后又增加了一些新的思路。
在Java中实现的单例模式的思路有很多,但是比较好的两个思路是利用类加载机制生成单例对象check-lock-check机制避免并发问题
我们给出这两个思路的Java代码,
利用类加载机制初始化类的静态变量,在类加载过程中的初始化阶段,会执行程序员编写的赋值语句和静态代码块,生成一个单例对象,并且这个生成过程只会执行一次,保证只生成一个单例对象。

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton (){}
    public static Singleton getInstance() {
    	return instance;
    }
}

check-lock-check机制,又被称为双检锁机制,第一次检查,如果已经生成了单例,就直接返回这个对象,如果还未生成单例对象,先上锁,避免多个线程去创建单例对象,再一次检查,是因为当有多个线程进入了第一次检查,我们只允许第一个进入锁的线程创建对象,其他线程都不要再创建对象。(此外volatile是为了让创建对象过程中严格遵守:分配内存,初始化,赋值引用的顺序,这里不再详细介绍,具体内容见另一篇文章,Java与设计模式)

public class Singleton {
    private volatile static Singleton singleton;
    private Singleton (){}
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
    	return singleton;
    }
}

我们可以直接照猫画虎吗?显然第一种方法是不可以,没有办法利用类加载机制。
来看第二种方法,我们使用了Mutex进行了加锁操作。

type singleton struct{}
var instance *singleton
var mu sync.Mutex
func GetSingleton() *singleton {
    if instance == nil {
        mu.Lock()
        defer mu.Unlock()
        if instance == nil {
            instance = &singleton{}
        }
    }
    return instance
}

此外,Go 语言在 sync 包中提供了 Once 机制能够帮助我们写出更加优雅的代码,Once 是一个结构体,在执行 Do 方法的内部通过 atomic 操作和加锁机制来保证并发安全,且 once.Do 能够保证多个 goroutine 同时执行时 &singleton{} 只被创建一次

package singleton
import "sync"
type singleton struct{}
var instance *singleton
var once sync.Once
func GetSingleton() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

标签:singleton,Java,Singleton,Golang,instance,单例,设计模式
From: https://www.cnblogs.com/DCFV/p/18254768

相关文章

  • Golang语言基础超详细教程&备忘录
    作者的话:这篇文章是之前刚从Java转到Go,学习时编写的,力求全面且详细。本文是基础内容,适合初学者,也适合老手用来当备忘录。和网上其他文档不同的是,我陆陆续续将很多小的知识点也补进来了,后续也会继续补充。这篇文章开始是我写在本机,然后又改写到自己的个人博客,现在有誊写到CSDN,......
  • golang中用chan实现迭代器
    实现代码如下:packagemainimport( "log" "time")/* 两种迭代器的实现*///采用index的方式实现(非线程安全)typeListStructstruct{ indexint data[]int}func(sl*ListStruct)Next()int{ d:=sl.data[sl.index] sl.index+=1 returnd}func(......
  • 持续总结中!2024年面试必问 20 道设计模式面试题(二)
    上一篇地址:持续总结中!2024年面试必问20道设计模式面试题(一)-CSDN博客三、请描述单例模式(SingletonPattern)及其使用场景。单例模式是一种创建型设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这种模式在软件系统中非常常见,因为它提供了一种控制实......
  • rust 和 golang 的特点及适用场景
     Rust特点及适用场景:内存安全:Rust通过所有权系统和生命周期管理在编译时保证内存安全,有效防止了空指针异常、数据竞争、悬挂指针等问题,非常适合开发高性能系统软件和底层库。并发模型:Rust提供了强大的并发工具,如async/await和通道(channel),支持高效且安全......
  • golang flag 包
    Go语言的flag包用于命令行参数的解析。你可以通过定义参数来使用它。以下是一些使用flag包的常见方法:使用flag.String()定义一个字符串参数。使用flag.Int()定义一个整数参数。使用flag.Parse()解析命令行参数。使用flag.Args()获取未解析的参数。以下是一个简单的示例,演......
  • OO设计模式中的工厂模式
    读书笔记:New具体类实例即为针对实现编程,因为因此而在代码中具体化了一个类,将来会有可能带来修改,而如果针对接口编程,即在代码中用抽象类代替具体类,则不易于引起修改。简单工厂:严格来说不是设计模式,只是编程良好规范,将易于变化的部分抽取出来封装。工厂方法:定义了创建对象的框......
  • c/c++设计模式--备忘录模式
    #include<iostream>#include<vector>#ifdef_DEBUG//只在Debug(调试)模式下#ifndefDEBUG_NEW#defineDEBUG_NEWnew(_NORMAL_BLOCK,__FILE__,__LINE__)//重新定义new运算符#definenewDEBUG_NEW#endif#endif//#include<boost/type_index.hpp>usingna......
  • 【四种语言一网打尽(C\C++\Python\Golang)】L1-012 计算指数
    L1-012计算指数真的没骗你,这道才是简单题——对任意给定的不超过10的正整数n,要求你输出2^n。不难吧?输入格式:输入在一行中给出一个不超过10的正整数n。输出格式:在一行中按照格式2^n=计算结果输出2^n的值。输入样例:5输出样例:2^5=32C语言参考......
  • 【四种语言一网打尽(C\C++\Python\Golang)】L1-009 N个数求和
    L1-009N个数求和本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。输入格式:输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1a2/b2…给出N个有理数。题目保证所有分子和分母都在长整型范围......
  • 设计模式-门面模式
    门面模式门面模式(FacadePattern),又叫外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其重要特征时定义了一个高层接口,让子系统更容易使用,属于结构型模式门面模式,静态模式,委派模式门面模式就是特殊的静态代理模式门面模式重点在于封装,静态代理重点在于增强。委......