Python 3 | 56ms | Lock vs Event
The fastest solution for the problem is to use Lock mechanism. See the following code with comments:\npython3\nimport threading\n\nclass Foo:\n    def __init__(
The fastest solution for the problem is to use Lock mechanism. See the following code with comments:\n```python3\nimport threading\n\nclass Foo:\n    def __init__(self):\n\t\t# create lock to control sequence between first and second functions\n        self.lock1 = threading.Lock()\n\t\tself.lock1.acquire()\n\t\t\n\t\t# create another lock to control sequence between second and third functions\n        self.lock2 = threading.Lock()\n        self.lock2.acquire()\n\n    def first(self, printFirst: \'Callable[[], None]\') -> None:\n        printFirst()\n\t\t\n\t\t# since second function is waiting for the lock1, let\'s release it\n        self.lock1.release()\n\n    def second(self, printSecond: \'Callable[[], None]\') -> None:\n\t\t# wait for first funtion to finish\n        self.lock1.acquire()\n        \n\t\tprintSecond()\n\t\t\n\t\t# let\'s release lock2, so third function can run\n        self.lock2.release()\n\n    def third(self, printThird: \'Callable[[], None]\') -> None:\n\t\t# wait for second funtion to finish\n        self.lock2.acquire()\n\t\t\n        printThird()\n```\nNow, when I was solving the problem the result was showing only 76 ms, which is far from the fastest. If you encounter similar issue take into account that you are working with threading and the timing is very unpredictable when CPU decides to switch threads. This can cause different timing results.\n\nAs an alternative you can use other synchronization mechanisms, such as Semaphore or Event. If you peek into CPython code you will see both Event and Semaphore are using Lock inside. That means that technically Lock solution is the fastest.\n\nBut for the reference here is solution with Event synchronization. In my opinion it looks little better:\n\n```python3\nimport threading\n\nclass Foo:\n    def __init__(self):\n        self.event1 = threading.Event()\n        self.event2 = threading.Event()\n\n    def first(self, printFirst: \'Callable[[], None]\') -> None:\n        printFirst()\n        self.event1.set()\n\n    def second(self, printSecond: \'Callable[[], None]\') -> None:\n        self.event1.wait()\n        printSecond()\n        self.event2.set()\n\n    def third(self, printThird: \'Callable[[], None]\') -> None:\n        self.event2.wait()\n        printThird()\n```
['Python', 'Python3']