Go - 3 solutions (Channels, Mutex and Atomic Operations)
Channels vs Mutex vs Atomic Operations\n\nChannels : When goroutines needs to communicate.\n\nMutex : When goroutines needs shared variable.\n\nAtomic operation
# Channels vs Mutex vs Atomic Operations\n\nChannels : When goroutines needs to communicate.\n\nMutex : When goroutines needs shared variable.\n\nAtomic operations : When it\'s known that lock will be quickly released and acquired. So your process remains in CPU (wasting CPU cycle) instead of getting removed back and forth (so saves on context switching).\n\n# Channels\n\nRuntime : 4 ms\n```golang []\ntype FooBar struct {\n\tn   int\n\tchA chan struct{}\n\tchB chan struct{}\n}\n\nfunc NewFooBar(n int) *FooBar {\n\tf := FooBar{n: n}\n\tf.chA = make(chan struct{}, 1)\n\tf.chB = make(chan struct{}, 1)\n\treturn &f\n}\n\nfunc (fb *FooBar) Foo(printFoo func()) {\n\tfor i := 0; i < fb.n; i++ {\n\t\t// printFoo() outputs "foo". Do not change or remove this line.\n\t\tif i > 0 {\n\t\t\t<-fb.chB\n\t\t}\n\t\tprintFoo()\n\t\tfb.chA <- struct{}{}\n\t}\n}\n\nfunc (fb *FooBar) Bar(printBar func()) {\n\tfor i := 0; i < fb.n; i++ {\n\t\t// printBar() outputs "bar". Do not change or remove this line.\n\t\t<-fb.chA\n\t\tprintBar()\n\t\tfb.chB <- struct{}{}\n\t}\n\n}\n```\n\n# Mutex\nRuntime : 29 ms\n```golang []\n\ntype FooBar struct {\n\tn     int\n\tm     sync.Mutex\n\taTurn bool\n}\n\nfunc NewFooBar(n int) *FooBar {\n\tf := FooBar{n: n, aTurn: true}\n\treturn &f\n}\n\nfunc (fb *FooBar) Foo(printFoo func()) {\n\tfor i := 0; i < fb.n; {\n\t\t// printFoo() outputs "foo". Do not change or remove this line.\n\t\tfb.m.Lock()\n\t\tif fb.aTurn {\n\t\t\tprintFoo()\n\t\t\tfb.aTurn = false\n            i++\n\t\t}\n\t\tfb.m.Unlock()\n\t}\n}\n\nfunc (fb *FooBar) Bar(printBar func()) {\n\tfor i := 0; i < fb.n; {\n\t\t// printBar() outputs "bar". Do not change or remove this line.\n\t\tfb.m.Lock()\n\t\tif !fb.aTurn {\n\t\t\tprintBar()\n\t\t\tfb.aTurn = true\n            i++\n\t\t}\n\t\tfb.m.Unlock()\n\t}\n\n}\n```\n\n# Atomic Operations\nRuntime : 23 ms\n```golang []\n\ntype FooBar struct {\n\tn     int\n\taTurn int32\n}\n\nfunc NewFooBar(n int) *FooBar {\n\tf := FooBar{n: n, aTurn: 0}\n\treturn &f\n}\n\nfunc (fb *FooBar) Foo(printFoo func()) {\n\tfor i := 0; i < fb.n; i++ {\n\t\t// printFoo() outputs "foo". Do not change or remove this line.\n\t\tfor !atomic.CompareAndSwapInt32(&fb.aTurn, 0, 0) {\n\t\t}\n\t\tprintFoo()\n\t\tatomic.StoreInt32(&fb.aTurn, 1)\n\t}\n}\n\nfunc (fb *FooBar) Bar(printBar func()) {\n\tfor i := 0; i < fb.n; i++ {\n\t\t// printBar() outputs "bar". Do not change or remove this line.\n\t\tfor !atomic.CompareAndSwapInt32(&fb.aTurn, 1, 1) {\n\t\t}\n\t\tprintBar()\n\t\tatomic.StoreInt32(&fb.aTurn, 0)\n\t}\n\n}\n```
['Concurrency', 'Go']