We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
给出的demo代码的确能跑通,但是利用sync.Once.Do()方法实现线程安全的话,会导致整个go进程中只能创建这一种单例 如果我想创建多个用处不同的单例的话,会导致后面的都没法成功
想了两种优化的方案
package singleton import ( "sync" ) // Singleton 是单例模式接口,导出的 // 通过该接口可以避免 GetInstance 返回一个包私有类型的指针 type Singleton interface { foo() } // singleton 是单例模式类,包私有的 type singleton struct{} func (s singleton) foo() {} var ( instance *singleton instance2 *singleton2 mu sync.Mutex ) //GetInstance 用于获取单例模式对象 func GetInstance() Singleton { mu.Lock() defer mu.Unlock() if instance == nil { instance = &singleton{} } return instance } type singleton2 struct { } func (s2 singleton2) foo() {} func GetInstance2() Singleton { mu.Lock() defer mu.Unlock() if instance2 == nil { instance2 = &singleton2{} } return instance2 }
package singleton import ( "sync" "sync/atomic" ) // Singleton 是单例模式接口,导出的 // 通过该接口可以避免 GetInstance 返回一个包私有类型的指针 type Singleton2 interface { foo() } // singleton 是单例模式类,包私有的 type singleton21 struct{} func (s singleton21) foo() {} var ( instance21 *singleton21 instance22 *singleton22 initInstanceCnt uint32 initInstanceCnt2 uint32 mu sync.Mutex ) //GetInstance 用于获取单例模式对象 func GetInstance21() Singleton2 { if atomic.LoadUint32(&initInstanceCnt) == 1 { return instance21 } mu.Lock() defer mu.Unlock() if initInstanceCnt == 0 { instance21 = &singleton21{} atomic.StoreUint32(&initInstanceCnt, 1) } return instance21 } type singleton22 struct { } func (s2 singleton22) foo() {} func GetInstance22() Singleton { if atomic.LoadUint32(&initInstanceCnt2) == 1 { return instance22 } mu.Lock() defer mu.Unlock() if initInstanceCnt2 == 0 { instance22 = &singleton22{} atomic.StoreUint32(&initInstanceCnt2, 1) } return instance22 }
The text was updated successfully, but these errors were encountered:
我觉得这方面用什么上锁模式其实没什么太大差别。用互斥锁、原子变量还是用Once。(其实Once内部实现就是原子变量),就是看起来语意更清晰一些。
就算用Once,也可以实现多个实例 也就是多一个Once,还有工厂函数和全局变量。
Sorry, something went wrong.
我觉得这方面用什么上锁模式其实没什么太大差别。用互斥锁、原子变量还是用Once。(其实Once内部实现就是原子变量),就是看起来语意更清晰一些。 就算用Once,也可以实现多个实例 也就是多一个Once,还有工厂函数和全局变量。
你说的有道理,我后来又试了一下,的确是声明多个once就可以了。看来是我误解了sync.Once.Do()的用法
No branches or pull requests
给出的demo代码的确能跑通,但是利用sync.Once.Do()方法实现线程安全的话,会导致整个go进程中只能创建这一种单例
如果我想创建多个用处不同的单例的话,会导致后面的都没法成功
想了两种优化的方案
The text was updated successfully, but these errors were encountered: