title: How to use RWMutex?
body: <pre><code>type Stat struct {
      counters     map[string]*int64
      countersLock sync.RWMutex
      averages     map[string]*int64
      averagesLock sync.RWMutex
  }
  </code></pre>
  
  <p>It is called below</p>
  
  <pre><code>func (s *Stat) Count(name string) {
      s.countersLock.RLock()
      counter := s.counters[name]
      s.countersLock.RUnlock()
      if counter != nil {
          atomic.AddInt64(counter, int64(1))
          return
      }
  }
  </code></pre>
  
  <p>My understanding is that we first lock the receiver s (which is a type Stat) and then we add to it if the counter does exist.</p>
  
  <p>Questions:</p>
  
  <p>Q1: why do we need to lock it? What does <code>RWMutex</code> even mean?</p>
  
  <p>Q2: <code>s.countersLock.RLock()</code> - does this lock up the entire receiver s or only the counters field in type Stat?</p>
  
  <p>Q3: <code>s.countersLock.RLock()</code> - does this lock up the averages field?</p>
  
  <p>Q4: Why should we use <code>RWMutex</code>? I thought channel was the preferred way to handle concurrency in Golang?</p>
  
  <p>Q5: What is this <code>atomic.AddInt64</code>. Why do we need atomic in this case? </p>
  
  <p>Q6: Why would we unlock right before we add to it?</p>