单例模式

单例分为饿汉式和懒汉式

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

单例模式的优缺点

优点:

(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()
}
**
posted @   Notomato  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示