sync

Mutex

valMutex.Lock() - locks the mutex

valMutex.Unlock() - unlocks the mutex

type Counter struct {
	valMutex sync.Mutex
	val      int
}

func Add(c *Counter) {
	for i := 0; i < 1000; i++ {
		c.valMutex.Lock()
		c.val += 1
		c.valMutex.Unlock()
	}
}

func main() {
	c := Counter{val: 0}
	for i := 0; i < 10; i++ {
		go Add(&c)
	}
	time.Sleep(1 * time.Second)
	println(c.val)
}

Wait Group

This allows you to ensure that all goroutines complete before continuing

var group sync.WaitGroup - create wait group

group.Add(1) - add an entry to the wait group

defer group.Done() - remove entry when goroutine is done

group.Wait() - wait for wait group to get back down to 0

type Counter struct {
	valMutex sync.Mutex
	val      int
}

func Add(c *Counter, group *sync.WaitGroup) {
	defer group.Done()
	for i := 0; i < 1000; i++ {
		c.valMutex.Lock()
		c.val += 1
		c.valMutex.Unlock()
	}
}

func main() {
	var group sync.WaitGroup

	c := Counter{val: 0}
	for i := 0; i < 10; i++ {
		group.Add(1)
		go Add(&c, &group)
	}

	group.Wait()

	println(c.val)
}