Golang中init()和sync.Once的区别

12

我看到Go语言中使用单例模式的两种方法。

  1. 使用 init() 函数
  2. 在sync包中使用 sync.Once

它们之间有什么区别?就线程安全而言哪一个更好?

如果 init() 可以解决所有问题,那么 sync.Once 用来做什么?


8
init是由运行时调用的,而sync.Do则在您的控制之下;您决定是否调用它、何时调用它以及它要做什么。 - Peter
1
你的测试不能决定不调用 init()init() 在你可能执行的任何命令行处理之前运行。 - David Maze
为什么这个问题一直被暂停? - lokanadham100
由于原因是它主要基于观点,因此它被暂停了。 “哪一个最好?”完全是主观的 - 这就是为什么两种方法都存在的原因。每种方法都适用于不同的情况。 - Jonathan Hall
1
如果你把问题简化为“有什么区别?”,那么它有可能会重新开放。至少它不再是基于观点的。然而,它仍然缺乏研究努力,所以我怀疑很少有人会投票重新开放它。 - Jonathan Hall
1个回答

21

包的init()函数被规范保证只会被调用一次,并且从单个线程调用(虽然它们可以启动goroutine,但是它们是线程安全的,除非你让它们多线程)。

使用sync.Once的原因是控制代码何时执行。 包的init()函数将在应用程序启动时调用,没有例外。 sync.Once允许您执行诸如延迟初始化的操作,例如第一次请求时创建资源(但仅一次,以防同时进行多个“第一次”请求),而不是在应用程序启动时; 或者仅在实际需要时才初始化资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接