[关闭]
@aliasliyu4 2016-09-01T10:38:28.000000Z 字数 826 阅读 3308

golang 单例模式的最佳实践

单例常用在固定资源的调用上,比如配置文件的加载之后,代码各处都可以使用。

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. //单例定义
  8. type Single struct {
  9. Sone *One
  10. Stwo *Two
  11. }
  12. type One struct {
  13. One string
  14. }
  15. type Two struct {
  16. Two string
  17. }
  18. //定义锁
  19. var (
  20. singleton *Single
  21. lock sync.Mutex
  22. )
  23. func NewSingle() *Single {
  24. //这里假设有两个goroutine,一个在第一个条件,一个在第二个条件
  25. //这就避免了加start函数执行两次的问题,也就是是一个实在的单例
  26. //尽量不要用defer,因为这虽然是方便,但是会带来不必要的开销
  27. if singleton == nil {
  28. lock.Lock()
  29. if singleton == nil {
  30. fmt.Println("shoule enter only!")
  31. singleton = start()
  32. }
  33. lock.Unlock()
  34. }
  35. return singleton
  36. }
  37. func start() *Single {
  38. one := one()
  39. two := two()
  40. single := &Single{
  41. Sone: one,
  42. Stwo: two,
  43. }
  44. return single
  45. }
  46. func one() *One {
  47. one := &One{
  48. One: "one",
  49. }
  50. return one
  51. }
  52. func two() *Two {
  53. two := &Two{
  54. Two: "two",
  55. }
  56. return two
  57. }
  58. func main() {
  59. //1000个goroutine执行单例,可以看到的结果是单例只初始化了一次
  60. for i := 0; i < 1000; i++ {
  61. go func() {
  62. single := NewSingle()
  63. fmt.Println(single)
  64. }()
  65. }
  66. //防止main.goroutine退出,导致其他goroutine不能被执行
  67. time.Sleep(time.Second * 6)
  68. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注