go设计模式之单例模式

单例模式在系统设计中很常用,如数据库的连接对象等,该类只有一个实例存在,实现很简单,就是在创建实例时,判断一下,实例是否已经存在。

以下使用go语言实现单例模式

package main

import "fmt"

type Manager struct {
	id int
}

func (m *Manager) Print() {
	fmt.Println("我是独有的", m.id)
}

var m *Manager

func GetInstance() *Manager {
	if m == nil {
  	m = &Manager{
  		id: 123,
	}
  }
  return m
}

func main() {
	manger :=GetInstance()
	manger.Print()
}

以上,我们实现了一个简单的单例,但存在一个问题,在并发场景下,如果线程1获取到 m =nil,执行创建,线程2也获取到m =nil,也会执行实例创建,为了防止该问题出现,需要通过锁机制来解决该问题。在go语言下,有一个sync的包,他有一个对象once,有一个方法Do,内部实现了锁机制

再来看一下改进后的实现

package main

import (
	"fmt"
	"sync"
)

type Manager struct {
	id int
}

func (m *Manager) Print() {
	fmt.Println("我是独有的", m.id)
}

var m *Manager
var once sync.Once

func GetInstance() *Manager {
	once.Do(func (){
		m = &Manager{
			id: 123,
		}
	})
    return m
}

func main() {
	manger :=GetInstance()
	manger.Print()
}

以上实现了一个单例的demo, 看一下Do的方法

func (o *Once) Do(f func()) {
	if atomic.LoadUint32(&o.done) == 1 {
		return
	}
	// Slow-path.
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏c#开发者

Asp.net Webform 使用Repository模式实现CRUD操作代码生成工具

Asp.net Webform 使用Repository模式实现CRUD操作代码生成工具 介绍 该工具是通过一个github上的开源项目修改的原始作者https...

4408
来自专栏恰同学骚年

设计模式的征途—19.命令(Command)模式

在生活中,我们装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制一些电器的打开和关闭,例如电灯或换气扇。在购买开关时,用户并不知道它将来到底用于控制什...

562
来自专栏软件开发 -- 分享 互助 成长

C#调用java程序

前言: 最近跟项目组的人合作一个项目,由于之前我用的是java写的一个与android通信的程序,现在另一个同事来编写界面程序,由于C#编写起来比较方便,而我又...

2816
来自专栏一个爱瞎折腾的程序猿

在asp.net core2.1中添加中间件以扩展Swashbuckle.AspNetCore3.0支持简单的文档访问权限控制

在此之前的接口项目中,若使用了 Swashbuckle.AspNetCore,都是控制其只在开发环境使用,不会就这样将其发布到生产环境(安全第一) 。 那么,...

1621
来自专栏圣杰的专栏

事件总线知多少(2)

源码路径:Github-EventBus 事件总线知多少(1) 事件总线知多少(2) 1.引言 之前的一篇文章事件总线知多少(1),介绍了什么是事件总线...

2337
来自专栏葡萄城控件技术团队

Asp.Net MVC4入门指南(8):给数据模型添加校验器

在本节中将会给Movie模型添加验证逻辑。并且确保这些验证规则在用户创建或编辑电影时被执行。 保持事情 DRY ASP.NET MVC 的核心设计信条之一是DR...

18510
来自专栏技术博客

Asp.Net Mvc3.0(MEF依赖注入实例)

在http://www.cnblogs.com/aehyok/p/3386650.html前面一节主要是对MEF进行简单的介绍。本节主要来介绍如何在Asp.Ne...

882
来自专栏liulun

基于.net开发chrome核心浏览器【五】

一:本篇将解决的问题 本章主要为了解决一下几个问题: 1.JsDialog的按钮错位的问题   我们开发出的浏览器,在有些操系统上调用alert,confirm...

2496
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(66)-MVC WebApi 用户验证 (2)

前言: 回顾上一节,我们利用webapi简单的登录并进行了同域访问与跨域访问来获得Token,您可以跳转到上一节下载代码来一起动手。 继续上一篇的文章,我们...

3948
来自专栏walterlv - 吕毅的博客

使用 Task.Wait()?立刻死锁(deadlock)

发布于 2017-10-27 15:54 更新于 2018-04...

921

扫码关注云+社区

领取腾讯云代金券