Print Numbers with Two Threads (Odd and Even)

Problem

Read n. One thread prints the odd numbers and another thread prints the even numbers from 1 to n. The output must be in the correct order: 1, 2, 3, ..., n, one number per line.

Constraints

  • 1 <= n <= 1000

Examples

Input

5

Output

1
2
3
4
5

Solutions

Best approachTime O(n)Space O(n)

Two threads must take turns. A shared lock with wait and notify lets a thread sleep when it is not its turn, and wakes it up when the other thread has printed.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Print in order with two threads.
 * Input   : One integer n.
 * Output  : The numbers 1 to n.
 * Approach: wait and notify.
 * Time    : O(n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // This method prints the numbers with the given parity (1 = odd, 0 = even). It waits when it is not its turn.
        static void printNumbers(Object lock, int[] next, int limit, String[] output, int parity) {
            synchronized (lock) {
                while (next[0] <= limit) {
                    if (next[0] % 2 == parity) {
                        output[next[0] - 1] = String.valueOf(next[0]);
                        next[0]++;

                        // Wake up the other thread.
                        lock.notifyAll();
                    } else {
                        try {
                            // Not my turn. Sleep until the other thread notifies.
                            lock.wait();
                        } catch (InterruptedException error) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                }
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(long n) {
        // Step 1: A shared object (lock) is used for wait and notify. "next" is the next number to print.
        final Object lock = new Object();
        final int[] next = {1};
        final int limit = (int) n;
        final String[] output = new String[limit];

        // Step 2: Both threads run the same code. A thread prints only when the next number has its parity (odd or even).
        Runnable odd = () -> printNumbers(lock, next, limit, output, 1);
        Runnable even = () -> printNumbers(lock, next, limit, output, 0);
        Thread oddThread = new Thread(odd);
        Thread evenThread = new Thread(even);
        oddThread.start();
        evenThread.start();

        // Step 3: Wait until both threads are finished.
        try {
            oddThread.join();
            evenThread.join();
        } catch (InterruptedException error) {
            Thread.currentThread().interrupt();
        }
        return output;
    }

    public static void main(String[] args) {
        long n = new Scanner(System.in).nextLong();
        System.out.println(String.join("\n", solve(n)));
    }
}
Hints (2)
  1. What does wait() do to a thread?
  2. Who calls notify?