python, classic Semaphore based solution explained
class FooBar:\n\n    def __init__(self, n):\n        self.n = n\n        self.foo_lock = threading.Semaphore(1)\n        self.bar_lock = threading.Semaphore(0)\
```class FooBar:\n\n    def __init__(self, n):\n        self.n = n\n        self.foo_lock = threading.Semaphore(1)\n        self.bar_lock = threading.Semaphore(0)\n\n    def foo(self, printFoo):\n        for i in range(self.n):\n            self.foo_lock.acquire()\n            printFoo()\n            self.bar_lock.release()\n\n    def bar(self, printBar):\n        for i in range(self.n):\n            self.bar_lock.acquire()\n            printBar()\n            self.foo_lock.release()\n```\n\t\nThink about semaphore as a count of available instance of a given resource. The `acquire()` reduces that number and `release()` increases.\n\t\nSo when we initialize class, we set `foo_lock` to 1, meaning it is ready to be printed, while `bar_lock` to 0 - meaning it has to wait.\n\nThen in both foo() and bar() we wait to acquire resource before we print and we release the other resource once we printed out string. \n\n
[]