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