Problem Description
Design a mechanism so that when three separate threads invoke the methods first(), second(), and third() concurrently, the output always prints "firstsecondthird". Even though the threads may be scheduled in any order, the method calls must be executed in the order: first() → second() → third().
Key Insights
- Threads can be scheduled in an unpredictable manner, so explicit synchronization is required.
- Use of synchronization primitives such as semaphores, locks, events, or countdown latches can enforce the required order.
- The key is to block the execution of second() until first() has finished, and similarly block third() until second() is done.
Space and Time Complexity
Time Complexity: O(1) per method call. Space Complexity: O(1) for the synchronization primitives.
Solution
We enforce the ordering by using synchronization primitives. In our solution, we use two signaling mechanisms:
- After executing first(), signal that second() is allowed to run.
- After executing second(), signal that third() is allowed to run. For example, in Python we might use threading.Event objects; in Java we can use CountDownLatch; in C++ we can use condition variables with mutexes; and in JavaScript we can simulate the behavior using promises. These structures ensure that each thread is blocked until the previous task has completed.