Zero values for sync.Mutex and sync.RWMutex are effective. So, pointers to mutexes are basically unnecessary.

Not recommended:

mu := new(sync.Mutex)
mu.Lock()

Recommended:

var mu sync.Mutex
mu.Lock()

If you use a pointer to a structure, the mutex should be a non-pointer field of the structure. Even if the structure is not exported, do not embed the mutex directly into the structure.

Not recommended:

type SMap struct {
  sync.Mutex

  data map[string]string
}

func NewSMap() *SMap {
  return &SMap{
    data: make(map[string]string),
  }
}

func (m *SMap) Get(k string) string {
  m.Lock()
  defer m.Unlock()

  return m.data[k]
}
// The Mutex field, Lock, and Unlock methods are a part of the SMap exported API without explicit declaration.

Recommended:

type SMap struct {
  mu sync.Mutex

  data map[string]string
}

func NewSMap() *SMap {
  return &SMap{
    data: make(map[string]string),
  }
}

func (m *SMap) Get(k string) string {
  m.mu.Lock()
  defer m.mu.Unlock()

  return m.data[k]
}
// The mutex and its methods are implementation details of SMap and are not visible to its callers.