# Go Example Code Go is an awesome language. ## Threads ```go package main import ( "fmt" "time" ) func main() { go runThread(2, "a") go runThread(1, "b") time.Sleep(3 * time.Second) } func runThread(seconds int, name string) { time.Sleep(time.Duration(seconds) * time.Second) fmt.Println("thread", name) } ``` ## Waitgroup ```go package main import ( "fmt" "time" "sync" ) func main() { var wg sync.WaitGroup; go runThread(2, "a", &wg) wg.Add(1) go runThread(1, "b", &wg) wg.Add(1) wg.Wait() fmt.Println("done") } func runThread(seconds int, name string, wg *sync.WaitGroup) { time.Sleep(time.Duration(seconds) * time.Second) fmt.Println("thread", name) wg.Done() } ``` ## Mutex ```go package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup; var mx sync.Mutex; go runThread("a", &mx, &wg) wg.Add(1) go runThread("b", &mx, &wg) wg.Add(1) wg.Wait() } func runThread(name string, mx *sync.Mutex, wg *sync.WaitGroup) { mx.Lock() fmt.Println("in critical section", name) time.Sleep(2 * time.Second) mx.Unlock() wg.Done() } ``` ## Channels ```go package main import ( "fmt" "time" ) func main() { // channel will buffer up to 2 strings ch := make(chan string, 2) go runThread("a", 3, ch) go runThread("b", 2, ch) msg1 := <-ch fmt.Println(msg1) msg2 := <-ch fmt.Println(msg2) } func runThread(name string, sleep int, ch chan string) { time.Sleep(time.Duration(sleep) * time.Second) ch <- "message from thread " + name } ``` ## Atomic ```go package main import ( "fmt" "sync" "sync/atomic" ) func main() { var ops uint64 // will be edited across threads var wg sync.WaitGroup for i := 0; i < 50; i++ { // create 50 threads wg.Add(1) // fire a goroutine w/ functional programming too go func() { for c := 0; c < 1000; c++ { atomic.AddUint64(&ops, 1) // atomic operation } wg.Done() }() } wg.Wait() fmt.Println("ops:", ops) } ```