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......
    
    }

    ~~~

  • 相关阅读:
    createpipe
    JavaScript中的JSON(非原创一)
    Delphi资源文件的应用(转)
    PowerDesigner15对SQL2005反向工程问题.
    readonly(C# 参考)
    SQL SERVER 2005 数据挖掘与商业智能完全解决方案学习笔记(四)
    什么是Actor?
    ORACLE自增长字段实现(转)
    SQL SERVER 2005 数据挖掘与商业智能完全解决方案学习笔记(二)
    J2EE框架(TomcatStrutsHibernateSpringAjax(dojo))开发步骤:
  • 原文地址:https://www.cnblogs.com/paulwhw/p/15450657.html
Copyright © 2011-2022 走看看