title: When should you use a mutex over a channel?
body: <p>For the past few weeks I've been wrestling with one (not-so) simple question:</p>
  
  <h3>When is it best to use a <code>sync.Mutex</code> and, conversely, when is it best use a <code>chan</code>?</h3>
  
  <p>It seems that for a lot of problems either strategy is interchangeable with the other - <em>and that's just the problem!</em></p>
  
  <p>Take <a href="https://youtu.be/QDDwwePbDtw?t=2m55s" rel="noreferrer">this video</a> found in the Golang documentation. Below, I've taken the liberty to dictate the code in the playground and also translate it to a <code>sync.Mutex</code> equivalent.</p>
  
  <h3>Is there a certain problem - encountered in the real world - that warrants the use of one other?</h3>
  
  <p>Notes:</p>
  
  <ul>
  <li>I am a huge fan of <a href="https://github.com/junegunn/fzf/blob/master/src/matcher.go#L153" rel="noreferrer">this use of chan</a> and struggle to think of a more elegant implementation using sync.Mutex.</li>
  <li>It's worth noting that the <code>chan</code> implementation does more work in the same time (reaches 12)*</li>
  </ul>
  
  <p>Playgrounds:</p>
  
  <ul>
  <li><a href="https://play.golang.org/p/u2pAJ6soNd" rel="noreferrer">Chan implementation</a> </li>
  <li><a href="https://play.golang.org/p/lxtd2yQYe0" rel="noreferrer">Mutex implementation</a></li>
  </ul>
  
  <p>Ping/pong with <code>chan</code>:</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "time"
  )
  
  type Ball struct { hits int }
  
  func main() {
      table := make(chan *Ball)
      go player("ping", table)
      go player("pong", table)
  
      table &lt;- new(Ball)
      time.Sleep(1 * time.Second)
      &lt;-table
  }
  
  func player(name string, table chan *Ball) {
      for {
          ball := &lt;-table
          ball.hits++
          fmt.Println(name, ball.hits)
          time.Sleep(100 * time.Millisecond)
          table &lt;- ball
      }
  }
  </code></pre>
  
  <p>Ping/pong with <code>sync.Mutex</code>:</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "time"
      "sync"
  )
  
  type Ball struct { hits int }
  
  var m =  sync.Mutex{}
  
  func main() {
      ball := new(Ball)
      go player("ping", ball)
      go player("pong", ball)
  
      time.Sleep(1 * time.Second)
  }
  
  func player(name string, ball *Ball) {
      for {
          m.Lock()
          ball.hits++
          fmt.Println(name, ball.hits)
          time.Sleep(100 * time.Millisecond)
          m.Unlock()
  
      }
  }
  </code></pre>