title: Is there a difference in Go between a counter using atomic operations and one using a mutex?
body: <p>I have seen some discussion lately about whether there is a difference between a counter implemented using atomic increment/load, and one using a mutex to synchronise increment/load.</p>
  
  <p>Are the following counter implementations functionally equivalent?</p>
  
  <pre><code>type Counter interface {
      Inc()
      Load() int64
  }
  
  // Atomic Implementation
  
  type AtomicCounter struct {
      counter int64
  }
  
  func (c *AtomicCounter) Inc() {
      atomic.AddInt64(&amp;c.counter, 1)
  }
  
  func (c *AtomicCounter) Load() int64 {
      return atomic.LoadInt64(&amp;c.counter)
  }
  
  // Mutex Implementation
  
  type MutexCounter struct {
      counter int64
      lock    sync.Mutex
  }
  
  func (c *MutexCounter) Inc() {
      c.lock.Lock()
      defer c.lock.Unlock()
  
      c.counter++
  }
  
  func (c *MutexCounter) Load() int64 {
      c.lock.Lock()
      defer c.lock.Unlock()
  
      return c.counter
  }
  </code></pre>
  
  <p>I have run a bunch of test cases (<a href="https://play.golang.org/p/oHnikFHlWq" rel="noreferrer">Playground Link</a>) and haven't been able to see any different behaviour. Running the tests on my machine the numbers get printed out of order for all the <code>PrintAll</code> test functions.</p>
  
  <p>Can someone confirm whether they are equivalent or if there are any edge cases where these are different? Is there a preference to use one technique over the other? The <a href="https://golang.org/pkg/sync/atomic/" rel="noreferrer">atomic documentation</a> does say it should only be used in special cases.</p>
  
  <p><strong>Update:</strong>
  The original question that caused me to ask this was <a href="https://stackoverflow.com/q/47422284/8930534">this one</a>, however it is now on hold, and i feel this aspect deserves its own discussion. In the answers it seemed that using a mutex would guarantee correct results, whereas atomics might not, specifically if the program is running in multiple threads. My questions are:</p>
  
  <ul>
  <li><strike>Is it correct that they can produce different results?</strike> (See update below. The answer is yes.).</li>
  <li>What causes this behaviour?</li>
  <li>What are the tradeoffs between the two approaches?</li>
  </ul>
  
  <p><strong>Another Update:</strong></p>
  
  <p>I've found some code where the two counters behave differently. When run on my machine this function will finish with <code>MutexCounter</code>, but not with <code>AtomicCounter</code>. Don't ask me why you would ever run this code:</p>
  
  <pre><code>func TestCounter(counter Counter) {
      end := make(chan interface{})
  
      for i := 0; i &lt; 1000; i++ {
          go func() {
              r := rand.New(rand.NewSource(time.Now().UnixNano()))
              for j := 0; j &lt; 10000; j++ {
                  k := int64(r.Uint32())
                  if k &gt;= 0 {
                      counter.Inc()
                  }
              }
          }()
      }
  
      go func() {
          prevValue := int64(0)
          for counter.Load() != 10000000 { // Sometimes this condition is never met with AtomicCounter.
              val := counter.Load()
              if val%1000000 == 0 &amp;&amp; val != prevValue {
                  prevValue = val
              }
          }
  
          end &lt;- true
  
          fmt.Println("Count:", counter.Load())
      }()
  
      &lt;-end
  }
  </code></pre>