返回顶部
首页 > 资讯 > 精选 >go单例怎么实现双重检测是否安全
  • 610
分享到

go单例怎么实现双重检测是否安全

2023-06-29 10:06:27 610人浏览 八月长安
摘要

这篇文章主要讲解了“Go单例怎么实现双重检测是否安全”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“go单例怎么实现双重检测是否安全”吧!现状当前有的项目直接使用Mutex锁,有的就直接判断n

这篇文章主要讲解了“Go单例怎么实现双重检测是否安全”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“go单例怎么实现双重检测是否安全”吧!

现状

当前有的项目直接使用Mutex,有的就直接判断nil则创建,对于前者,每次都加锁性能差,对于后者则会出现多个实例,也就不是单例了

改进

进而想要改进一下,在这不讨论饿汉和线程非安全的实现,对于go中线程安全的懒汉实现,常见两种:

双重检验sync.Once

双重检验示例:

package main import (    "sync"    "testing")var (    instance *int    lock      sync.Mutexfunc getInstance() *int {    if instance == nil {        lock.Lock()        defer lock.Unlock()        if instance == nil {            i := 1            instance = &i        }    }    return instance}// 用于下边基准测试func BenchmarkSprintf(b *testing.B){    for i:=0;i<b.N;i++{        go getInstance()

是否线程安全

基于java中双重检验锁的经验,因为JVM的内存模型,双重检验锁会出现可见性问题,可以通过 volatile解决
那么在go里会有类似问题吗?
关键点在于instance变量的读和写是否是原子操作
这里做了个race竞态检测:

go单例怎么实现双重检测是否安全

可以看到20行的写入和14行的读取发生了竞态
上例中用64位(系统是64位)的int指针表示一个实例,也说明了对于64位数据的写入和读取是非原子操作

我们看另一种实现:sync.Once方法

package main import (    "sync"    "testing")var (    instance *int    once      sync.Oncefunc getInstance() *int {    once.Do(func(){        if instance == nil {            i := 1            instance = &i        }    })    return instance}func BenchmarkSprintf(b *testing.B){    for i:=0;i<b.N;i++{        go getInstance()    }

实现比双重检验看起来要整洁许多

race检测结果:

go单例怎么实现双重检测是否安全

没有发生竞态

关于sync.Once

那么sync.Once是怎么实现的呢

看下源码

package sync import (   "sync/atomic")type Once struct {   done uint32   m    Mutex}func (o *Once) Do(f func()) {   if atomic.LoadUint32(&o.done) == 0 {      o.doSlow(f)   }func (o *Once) doSlow(f func()) {   o.m.Lock()   defer o.m.Unlock()   if o.done == 0 {      defer atomic.StoreUint32(&o.done, 1)      f()

可以看到sync.Once内部其实也是一个双重检验锁,但是对于共享变量(done字段)的读和写使用了atomic包的StoreUint32和LoadUint32方法

sync.Once使用一个32位无符号整数表示共享变量,即使是32位变量的读写操作都需要atomic包方法来实现原子性,更说明了go里边指针的读写不能保证原子性

感谢各位的阅读,以上就是“go单例怎么实现双重检测是否安全”的内容了,经过本文的学习后,相信大家对go单例怎么实现双重检测是否安全这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: go单例怎么实现双重检测是否安全

本文链接: https://lsjlt.com/news/324311.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • go单例怎么实现双重检测是否安全
    这篇文章主要讲解了“go单例怎么实现双重检测是否安全”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“go单例怎么实现双重检测是否安全”吧!现状当前有的项目直接使用Mutex锁,有的就直接判断n...
    99+
    2023-06-29
  • go单例实现双重检测是否安全的示例代码
    目录现状改进双重检验示例:是否线程安全关于sync.Once关于atomic和metex结论今天看到项目中的kafka客户端包装结构体的获取是单例模式<br>单例的实现是...
    99+
    2024-04-02
  • Go如何实现安全的双检锁
    这篇“Go如何实现安全的双检锁”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go如何实现安全的双检锁”文章吧。不安全的双检锁...
    99+
    2023-06-30
  • php怎么检测gd2是否安装
    本教程操作环境:windows7系统、PHP7.1版,DELL G3电脑php检测gd2是否安装的方法方法1、启动phpinfo()来确认GD2库,启动方法:在xampp目录下找到htdocs文件夹,进入文件夹新建一个后缀为.php的文件,...
    99+
    2016-09-11
    php gd2
  • Java怎么实现双重校验锁单例
    这篇文章主要介绍了Java怎么实现双重校验锁单例的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么实现双重校验锁单例文章都会有所收获,下面我们一起来看看吧。代码实现Java代码实现如下://双重校验锁单...
    99+
    2023-06-28
  • Go到底能不能实现安全的双检锁(推荐)
    目录不安全的双检锁sync.Once的启示安全的双检锁处理panic处理error有范围的单例双检锁的性能从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?有些同学可...
    99+
    2024-04-02
  • 怎么检测mongodb是否已经安装成功
    可以通过以下几种方法来检测MongoDB是否已经安装成功:1. 启动MongoDB服务:首先,使用命令行窗口(或终端)进入Mongo...
    99+
    2023-08-31
    mongodb
  • Java双重MD5加密怎么实现安全登录
    本篇内容主要讲解“Java双重MD5加密怎么实现安全登录”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java双重MD5加密怎么实现安全登录”吧!一:问题引入对存储在数据库中的密码进行解密操作:...
    99+
    2023-07-02
  • 基于FLink实现实时安全检测的示例代码
    目录研发背景场景描述组件版本日志结构技术方案关键代码主入口类mapper算子filter算子keyBy算子窗口函数(核心代码)最后一次map算子ElasticSearch工具类事件实...
    99+
    2023-02-23
    FLink实时安全检测 FLink安全检测 FLink检测
  • Python双端队列怎么实现回文检测
    本文小编为大家详细介绍“Python双端队列怎么实现回文检测”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python双端队列怎么实现回文检测”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、双端队列双端队列 ...
    99+
    2023-06-26
  • 怎么检查聚合器host.exe在Windows11中是否安全
    这篇“怎么检查聚合器host.exe在Windows11中是否安全”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下...
    99+
    2023-04-14
    windows11
  • GO中的单元测试怎么实现
    这篇“GO中的单元测试怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“GO中的单元测试怎么实现”文章吧。  ...
    99+
    2023-07-04
  • AJAX应用实例之如何实现检测用户名是否唯一功能
    小编给大家分享一下AJAX应用实例之如何实现检测用户名是否唯一功能,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!效果图如下所示:下面写一个简单的例子,检测用户名是否唯一(直接撸代码):前端...
    99+
    2024-04-02
  • C#中怎么实现ftp检测目录是否存在和创建文件夹
    本文小编为大家详细介绍“C#中怎么实现ftp检测目录是否存在和创建文件夹”,内容详细,步骤清晰,细节处理妥当,希望这篇“C#中怎么实现ftp检测目录是否存在和创建文件夹”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧...
    99+
    2023-07-02
  • 怎么用Shell脚本实现检测文件是否被修改过的功能
    本篇内容介绍了“怎么用Shell脚本实现检测文件是否被修改过的功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!#!/bin/bashfun...
    99+
    2023-06-09
  • Go语言单例模式怎么实现
    这篇文章主要介绍“Go语言单例模式怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Go语言单例模式怎么实现”文章能帮助大家解决问题。什么是单例模式单例模式指仅允许创建一个对象的设计模式。它通常...
    99+
    2023-07-05
  • javascript表单验证是否为空怎么实现
    这篇“javascript表单验证是否为空怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“javascript表单验证...
    99+
    2023-07-06
  • Go语言中的单例模式怎么实现
    本篇内容介绍了“Go语言中的单例模式怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是单例模式单例模式指仅允许创建一个对象的设计模...
    99+
    2023-07-05
  • 怎么用vbs实现自动检查代理是否可用
    本篇内容介绍了“怎么用vbs实现自动检查代理是否可用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!将下面代码中的地址改一下,存为ieprox...
    99+
    2023-06-08
  • Java中ConcurrentHashMap是怎么实现线程安全的
    这篇文章主要介绍“Java中ConcurrentHashMap是怎么实现线程安全的”,在日常操作中,相信很多人在Java中ConcurrentHashMap是怎么实现线程安全的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作