4 Python solutions
Solution 1:\n\nfrom threading import Event\nclass Foo:\ndef __init__(self):\n\tself.done = (Event(),Event())\n\ndef first(self, printFirst):\n\tprintFirst()\n\t
**Solution 1:**\n```\nfrom threading import Event\nclass Foo:\ndef __init__(self):\n\tself.done = (Event(),Event())\n\ndef first(self, printFirst):\n\tprintFirst()\n\tself.done[0].set()\n\ndef second(self, printSecond):\n\tself.done[0].wait()\n\tprintSecond()\n\tself.done[1].set()\n\ndef third(self, printThird):\n\tself.done[1].wait()\n\tprintThird()\n```\n\n**Solution 2:**\n```\nfrom threading import Barrier\nclass Foo:\n    def __init__(self):\n        self.first_barrier = Barrier(2)\n        self.second_barrier = Barrier(2)\n     def first(self, printFirst):\n        printFirst()\n        self.first_barrier.wait()\n     def second(self, printSecond):\n        self.first_barrier.wait()\n        printSecond()\n        self.second_barrier.wait()\n     def third(self, printThird):\n        self.second_barrier.wait()\n        printThird()\n```\n\n**Solution 3:**\n```\nfrom threading import Lock\nclass Foo:\n    def __init__(self):\n        self.locks = (Lock(),Lock())\n        self.locks[0].acquire()\n        self.locks[1].acquire()\n     def first(self, printFirst):\n        printFirst()\n        self.locks[0].release()\n     def second(self, printSecond):\n        with self.locks[0]:\n            printSecond()\n            self.locks[1].release()\n    def third(self, printThird):\n        with self.locks[1]:\n            printThird()\n```\n\n**Solution 4:**\n```\nfrom threading import Semaphore\nclass Foo:\n    def __init__(self):\n        self.gates = (Semaphore(0),Semaphore(0))\n    def first(self, printFirst):\n        printFirst()\n        self.gates[0].release()\n    def second(self, printSecond):\n        with self.gates[0]:\n            printSecond()\n            self.gates[1].release()\n    def third(self, printThird):\n        with self.gates[1]:\n            printThird()\n```
[]