zoukankan      html  css  js  c++  java
  • Python与Golang中实现单例模式

    Python中重写__new__方法实现

    import threading
    
    import configs
    
    
    class Util(object):
        _lock = threading.Lock()
    
        def __init__(self, host, port):
            self.host = host
            self.port = port
    
        # 重写 __new__ 方法实现单例模式
        # new方法里面实际上是创建了一个self对象,单例模式就是让new方法中生产同一个对象!
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, "_instance"):
                with cls._lock:
                    cls._instance = object.__new__(cls)
            return cls._instance
    
    
    if __name__ == '__main__':
        u1 = Util(configs.HOST, configs.PORT)
        u2 = Util(configs.HOST, configs.PORT)
        u3 = Util(configs.HOST, configs.PORT)
    
        print(id(u1), id(u2), id(u3))  # 140618541058200 140618541058200 140618541058200
        print(id(u1) == id(u2))  # True
        print(id(u2) == id(u3))  # True

    Go中实现1 - 终极写法

    package main
    
    import (
        "fmt"
        "os"
        "strconv"
        "sync"
    )
    
    // 参考资料里面有源码的分析以及sync.Once结构体的done为什么要放到最前面!
    // https://geektutu.com/post/hpg-sync-once.html
    
    type Config struct {
        Server string
        Port   int64
    }
    
    var (
        once   sync.Once
        config *Config
    )
    
    func ReadConfig() *Config {
        // 类似于 单例模式的实现!
        once.Do(func() {
            var err error
            config = &Config{Server: os.Getenv("TT_SERVER_URL")}
            config.Port, err = strconv.ParseInt(os.Getenv("TT_PORT"), 10, 0)
            if err != nil {
                config.Port = 8080
            }
            fmt.Println("init config......")
        })
    
        return config
    }
    
    func main() {
    
        // 开并发去初始化config
        wait := sync.WaitGroup{}
        for i := 0; i < 10; i++ {
            wait.Add(1)
            go func() {
                defer wait.Done()
                _ = ReadConfig()
            }()
        }
        wait.Wait()
    
        // 最后只打印一个:init config......
    
    }

    Go中实现2 - once.Do方法中的函数写在外面

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    // 参考资料里面有源码的分析以及sync.Once结构体的done为什么要放到最前面!
    // https://geektutu.com/post/hpg-sync-once.html
    
    type Config struct {
        Server string
        Port   int64
    }
    
    var (
        once   sync.Once
        config *Config
    )
    
    func initConfig() {
        // 这里模拟从文件或者环境变量中获取server与port
        config = &Config{Server: "127.0.0.1", Port: 9999}
    
        fmt.Println("init config......")
    }
    
    func ReadConfig(i int) *Config {
        fmt.Println("i>>> ", i)
        // 类似于 单例模式的实现!
        //initConfig()
        once.Do(initConfig)
        return config
    }
    
    func main() {
    
        // 开并发去初始化config
        wait := sync.WaitGroup{}
        for i := 0; i < 10; i++ {
            wait.Add(1)
            go func(i int) {
                defer wait.Done()
                _ = ReadConfig(i)
            }(i)
        }
        wait.Wait()
    
        // 最后只打印一个:init config......
    
    }

    ~~~

  • 相关阅读:
    Freemarker
    加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
    Jenkins入门
    kafka实战
    多线程文件下载
    Excel操作报表
    @Pointcut 使用@annotation 带参数
    博客园设置
    Windows下 tensorboard显示No graph definition files were found的问题解决
    通过GitHub Desktop 上传代码到github 远程仓库
  • 原文地址:https://www.cnblogs.com/paulwhw/p/15450657.html
Copyright © 2011-2022 走看看