首页 > 其他分享 >单例模式

单例模式

时间:2022-09-30 19:57:59浏览次数:42  
标签:singelton 单例 s2 s1 模式 func var

单例分为饿汉式和懒汉式

在初始化单例唯一指针的时候,就已经提前开辟好了一个对象,申请了内存。
饿汉式的好处是,不会出现线程并发创建,导致多个单例的出现,但是缺点是如果这个单例对象在业务逻辑没有被使用,也会客观的创建一块内存对象。那么与之对应的模式叫“懒汉式”
饿汉式需要加锁保证线程安全

单例模式的优缺点

优点:

(1) 单例模式提供了对唯一实例的受控访问。
(2) 节约系统资源。由于在系统内存中只存在一个对象。

缺点:

(1) 扩展略难。单例模式中没有抽象层。
(2) 单例类的职责过重。

适用场景

(1) 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
(2) 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

**package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

// 保证一个类永远只能有一个对象,且该对象的功能依然能被其他模块使用
// 非公有 首字母小写
//
type singelton struct {
}

// 饿汉式
var instance *singelton = new(singelton)

func Getinstance() *singelton {
	return instance
}

func t_hungary_singlton() {
	s1 := Getinstance()
	s2 := Getinstance()
	if s1 == s2 {
		fmt.Println("饿汉单例successful")
	}

}

// 懒汉式
var lazyinstance *singelton

func Getinstance1() *singelton {
	if lazyinstance == nil {
		lazyinstance = new(singelton)
	}
	return lazyinstance
}

func t_lazyinstance() {
	s1 := Getinstance1()
	s2 := Getinstance1()
	if s1 == s2 {
		fmt.Println("lazy instance successful")
	}
}

// 线程安全懒汉
var lock sync.Mutex
var safeinstance *singelton

func Getinstance2() *singelton {
	lock.Lock()
	defer lock.Unlock()
	if safeinstance == nil {
		safeinstance = new(singelton)
	}
	return safeinstance
}
func t_safeinstance() {
	s1 := Getinstance2()
	s2 := Getinstance2()
	if s1 == s2 {
		fmt.Println("safe lazy instance successful")
	}
}

// 其他方式的线程安全
var safe2lazyinstance *singelton
var lock2 sync.Mutex
var initiallazy uint32

func Getinstance3() *singelton {
	if atomic.LoadUint32(&initiallazy) == 1 {
		return safe2lazyinstance
	}
	lock2.Lock()
	defer lock2.Unlock()
	atomic.StoreUint32(&initiallazy, 1)
	safe2lazyinstance = new(singelton)
	return safe2lazyinstance
}

func t_safe2_lazyinstance() {
	s1 := Getinstance3()
	s2 := Getinstance3()
	if s1 == s2 {
		fmt.Println("atomic lazy instance successful")
	}
}

// Once 库的线程安全 本质上是包装了 上述的atomic

var once sync.Once
var oncesinge *singelton

func Getinstance4() *singelton {
	once.Do(func() {
		oncesinge = new(singelton)
	})
	return oncesinge
}

func t_once_singe() {
	s1 := Getinstance4()
	s2 := Getinstance4()
	if s1 == s2 {
		fmt.Println("once singelton successful")
	}
}
func main() {
	//饿汉式
	t_hungary_singlton()
	//	懒汉式
	t_lazyinstance()
	//	线程安全懒汉 用锁
	t_safeinstance()
	//	线程安全懒汉, 用atomic
	t_safe2_lazyinstance()
	//	线程安全懒汉, 用 sync.Once
	t_once_singe()
}
**

标签:singelton,单例,s2,s1,模式,func,var
From: https://www.cnblogs.com/notomatoes/p/16745945.html

相关文章

  • java 前后端开发模式简单说明
    实际上我以前写过一个简单的web前后端部署模式的说明,以下简单说明下关于java语言的,毕竟这个使用人群比较多参考图前后端彻底分离模式(都独立部署)  web使用基于......
  • Redis主从模式的实现
      前面说到了redis在单机的模式下是可以数据持久化的,但是不可以解决单点失败的问题,当单台redis服务器出现问题时,就可能会造成数据的丢失;想要解决这个问题的话我们可以使用......
  • 解释器模式 Interpreter
    “领域规则”模式在特定领域中,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将问题抽象为语法规则,从而给出在该领域下的一般性解决方案。典型模式Interp......
  • docker版redis-cluster模式集群-主从扩容
    3主3从节点在上篇:docker版redis-cluster模式集群搭建(3主3从)1、新建6387、6388两个节点dockerrun-d--nameredis-node-7--nethost--privileged=true-v/data/......
  • docker版redis-cluster模式集群搭建(3主3从)
    开放端口:开放Redis服务的两个TCP端口。譬如Redis客户端连接端口为6379,而Redis服务在集群中还有一个叫集群总线端口,其端口为客户端连接端口加上10000,即6379+10000=......
  • docker版redis-cluster模式集群-主从缩容
    接上篇扩容:docker版redis-cluster模式集群-主从扩容下线6387和63881、从集群中将4号从节点6388删除,并检查结果redis-cli--clusterdel-nodeip:从机端口从机......
  • NFT数藏盲盒+模式系统开发
    其实NFT未必一定是值钱、一定用来收藏,还有部分场景下,NFT是拿来用的,有自身的使用价值。 NFT20世纪的很长一段时间,体育卡收藏非常流行,但随着卡片供应量的增加,卡片生产商的......
  • 命令模式 Command
    “行为变化”模式在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间......
  • 职责链模式 Chain of Resposibility
    “数据结构”模式常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定数据结构封装在内部,在外部提......
  • 迭代器模式 Iterator
    “数据结构”模式常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定数据结构封装在内部,在外部提......