Alternate Odd and Even Numbers with Two Threads
Company: Omnissa
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
## Alternate Odd and Even Numbers with Two Threads
You are given a positive integer `n`. Print every integer from `1` to `n` in
strictly increasing order, but the printing work must be split across **exactly
two threads that run concurrently**:
- one thread (the **odd** thread) is responsible for printing all the odd numbers
(`1, 3, 5, ...`),
- the other thread (the **even** thread) is responsible for printing all the even
numbers (`2, 4, 6, ...`).
Because the two parities are interleaved (`1, 2, 3, 4, ...`), the threads must
cooperate so that the global output is still in order. After the odd thread
prints `1`, it must wait for the even thread to print `2`, which must wait for the
odd thread to print `3`, and so on. Use proper thread synchronization
(locks / condition variables / semaphores or the equivalent in your language) to
enforce this hand-off rather than relying on timing or unbounded busy-spinning.
Print the numbers as a single space-separated line, in order. Each number is
emitted by whichever thread owns its parity, but the final sequence read top to
bottom must be `1 2 3 ... n`.
### Examples
- `n = 1` -> `1`
- `n = 2` -> `1 2`
- `n = 5` -> `1 2 3 4 5` (odd thread emits `1 3 5`, even thread emits `2 4`)
- `n = 6` -> `1 2 3 4 5 6`
### Constraints
- `1 <= n <= 100000`
- You must use two separate threads and coordinate them with synchronization
primitives; a single-threaded loop that just prints `1..n` does not satisfy the
requirement.
- The two threads must terminate cleanly after `n` is printed (no deadlock, no
thread left blocked forever).
Quick Answer: This question evaluates a candidate's understanding of multithreading and synchronization primitives such as locks and condition variables. It tests the ability to coordinate two concurrent threads so that shared output is produced in a strict interleaved order, a common way interviewers assess practical concurrent-programming skills in coding interviews.
You are given a positive integer `n`. Produce every integer from `1` to `n` in strictly increasing order, but the work must be split across **exactly two threads that run concurrently**:
- the **odd** thread is responsible for the odd numbers (`1, 3, 5, ...`),
- the **even** thread is responsible for the even numbers (`2, 4, 6, ...`).
The two parities are interleaved (`1, 2, 3, 4, ...`), so the threads must cooperate: after the odd thread emits `1` it waits for the even thread to emit `2`, which waits for the odd thread to emit `3`, and so on. Use proper synchronization (locks / condition variables / semaphores or the equivalent in your language) to enforce this hand-off rather than relying on timing or unbounded busy-spinning. Both threads must terminate cleanly once `n` is reached (no deadlock, no thread left blocked forever).
**Return format (for grading):** return the ordered sequence `[1, 2, 3, ..., n]` as a list/array of integers, appended by whichever thread owns each number. Reading it top to bottom must give `1 2 3 ... n`.
### Examples
- `n = 1` -> `[1]`
- `n = 2` -> `[1, 2]`
- `n = 5` -> `[1, 2, 3, 4, 5]` (odd thread emits `1 3 5`, even thread emits `2 4`)
- `n = 6` -> `[1, 2, 3, 4, 5, 6]`
Constraints
- 1 <= n <= 100000
- Exactly two threads must be used, coordinated with synchronization primitives (locks / condition variables / semaphores).
- A single-threaded loop that just emits 1..n does not satisfy the requirement.
- Both threads must terminate cleanly after n is reached (no deadlock, no thread blocked forever).
Examples
Input: (1,)
Expected Output: [1]
Explanation: Boundary: only the odd thread emits 1; the even thread wakes, sees the counter past n, and exits.
Input: (2,)
Expected Output: [1, 2]
Explanation: Odd thread emits 1, hands off to the even thread which emits 2.
Input: (5,)
Expected Output: [1, 2, 3, 4, 5]
Explanation: Odd thread emits 1 3 5, even thread emits 2 4, interleaved into strict order.
Input: (6,)
Expected Output: [1, 2, 3, 4, 5, 6]
Explanation: Even count of numbers; last emission (6) comes from the even thread.
Input: (10,)
Expected Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Explanation: Larger run confirming the hand-off keeps global order across many turns.
Hints
- Share a single 'next number to print' counter plus a Condition (mutex + wait/notify) between the two threads.
- Each worker loops: acquire the lock, wait while the counter is still in range but its parity doesn't match this thread's parity, then emit the number, advance the counter, and notify the other thread.
- For clean termination, re-check the counter after waking: if it has passed n, notify_all() (so the peer also unblocks) and return instead of emitting.