一种解决方案是让您的柜台提供一个价值尽快更新的渠道 变化。通常,通过传达结果进行同步。比如你的 Couter 可能看起来像这样:
Couter
type Counter struct { value int ValueChange chan int } func (c *Counter) Change(n int) { c.value += n c.ValueChange <- c.value }
每当 Change 被调用,新值通过通道传递,无论是谁 等待值取消阻塞并继续执行,因此与之同步 计数器。使用此代码,您可以收听 ValueChange 对于这样的变化:
Change
ValueChange
v := <-c.ValueChange
同时打电话 c.Change 没问题了。
c.Change
有一个 在游戏中可运行的例子 。
在测试中,有时存在竞争条件,其中计数器高速缓存尚未由go例程更新。我目前在操作后使用1秒睡眠,以确保在测试计数器缓存之前已更新计数器缓存。
哎呀,我不想这么说,但是你做错了。 Go具有一流的功能,使并发变得容易!如果你正确使用它们,就不可能有竞争条件。
事实上,有一种工具可以 为你检测种族 。我敢打赌它抱怨你的程序。
简单的解决方案:
(另一种选择是使用锁。它会更高效,但编写起来要麻烦得多,并确保它是正确的。)