首页 > 其他分享 >单例模式-go语言实现

单例模式-go语言实现

时间:2023-02-05 22:55:34浏览次数:38  
标签:Singleton return 语言 单例 ins mu func go

一、理论知识

单例设计模式(Singleton Design Pattern)是指一个对象只允许被实例化一次,并提供一个访问该实例的全局访问点。

应用场景:

  1. 避免资源访问冲突,例如写日志文件操作;
  2. 表示业务概念上的全局唯一类,例如ID生成器、配置信息、连接池类等;

优点:

  • 减少了内存开销,尤其是频繁地创建和销毁实例时
  • 避免对资源的重复占用,例如文件操作

缺点:

  • 对OOP特性不友好
    • 以id生成器为例,如果采用了单例模式,就违背了基于接口而非实现的设计原则,也就违背了广义上的抽象特性,如果某一天需要替换id生成器时,成本很大。
  • 单例会隐藏类之间的依赖关系
    • 单例类不需要显示创建、不需要依赖参数传递,如果代码关系复杂时,调用关系会被隐藏得很隐蔽。
  • 单例对代码拓展性不友好
    • 单例模式模式只能有一个对象实例,如果某一天需要在代码中创建两个或多个实例,改动代价就特别大。例如如果采用了单例连接池,后续需要改造成两个连接池,一个普通sql、一个慢sql。

二、代码实现

package a_singleton

import "sync"

type Singleton struct{}

var ins *Singleton

// GetInstanceLazy 懒汉式。非并发安全。
func GetInstanceLazy() *Singleton {
	if ins == nil {
		ins = &Singleton{}
	}
	return ins
}

// GetInstanceLazyWithLock 懒汉式加锁,并发安全,但是性能差
var mu sync.Mutex
func GetInstanceLazyWithLock() *Singleton {
	mu.Lock()
	defer mu.Unlock()

	if ins == nil {
		ins = &Singleton{}
	}
	return ins
}

// GetInstanceLazyWithDoubleCheck 懒汉式-双重检查。并发安全,性能ok。
// Java版该实现存在CPU指令重排序问题,需要volatile关键字禁止指令重排序
func GetInstanceLazyWithDoubleCheck() *Singleton {
	if ins == nil {
		mu.Lock()
		defer mu.Unlock()

		if ins == nil {
			ins = &Singleton{}
		}
	}
	return ins
}

// GetInstanceHungry 饿汉式
var insHungry *Singleton = &Singleton{}
func GetInstanceHungry() *Singleton {
	return insHungry
}

// GetInstanceOnce 利用go自带并发工具sync.Once
var once sync.Once
func GetInstanceOnce() *Singleton {
	once.Do(func() {
		ins = &Singleton{}
	})
	return ins
}

标签:Singleton,return,语言,单例,ins,mu,func,go
From: https://www.cnblogs.com/csh24/p/17094134.html

相关文章

  • 数据结构与算法Python语言实现-第一章答案
    1.1编写一个Python函数is_multiple(n,m),用来接收两个整数值n和m,如果n是m的倍数,即存在整数i使得n=mi,那么函数返回True,否则返回Falsedefis_multiple......
  • golang变量
    1.golang变量命名规则由26个英文字母大小写,0-9,_组成。变量名不能以数字开头。变量都是先声明再使用,一旦声明必须使用。2.golang变量赋值方法2.1单个变量赋值......
  • c语言中共用栈的一个例子
    栈的其中一个作用:1.函数的返回地址和参数栈保存了一个函数调用时所需要的维护信息,可能和搭载另一个函数的栈一起返回函数的返回值(下面有一个例子)#include <stdio.h>#d......
  • 一步一步地完成题目——费解的开关(C/C++语言)递推、递归、顺序思维
    前言本文中博主将一步一步地、以正常人的顺序思维完成题目——费解的开关,使用的核心方法是递推与递归。题目参考题目:费解的开关详细的题目信息相信大家都已经知道了,因......
  • 【转载】R语言 面向对象编程
    转载自:R语言教程面向对象的编程侧重于数据和对象,而不是程序。面向对象的模型有助于我们对现实生活中的对象进行建模。为了在数据科学领域出类拔萃,掌握面向对象的编程概念......
  • 当Django出现django.template.exceptions.TemplateDoesNotExist: list_class.html 时
    修改settings配置文件,如下:    ......
  • GO 文件操作
    简介常见的文件操作:读、写、追加、复制,在go语言中标准库os提供了Openfile函数来进行此类操作,其原型如下:funcOpenFile(namestring,flagint,permFileMode)(file*Fi......
  • 【Django视图(View与APIView)】
    介绍1.继承django的View2.APIView和View的不同之处:a.传入到view方法中的是​​Request​​对象,而不是django的​​HttpRequest​​对象b.view方法可以返回​​Response​......
  • Casbin: 连续3年参加Google Summer of Code的开源授权技术领导者
    Casbin是一个开源的授权解决方案,很自豪的宣布它已经连续三年参加GoogleSummerofCode(GSoC)项目。Casbin是实现访问控制和授权管理的最受欢迎的开源项目之一。该项目广泛应......
  • 自学c语言小白求问
    intmain(){ inta=0; printf("买彩票,(中or没中):>\n"); scanf("%d",&a); switch(a) { case0:printf("娶白富美\n");break; case1:printf("敲代码\n");......