What is the difference between Go's wait groups and barriers for synchronizing and coordinating multiple goroutines in Go programs?