跳转至

两个线程交替打印 0~100 奇偶数

结论

synchronized + wait/notifyLock + Condition 都能实现。核心是两个线程共享一个状态变量,通过等待/唤醒切换执行权

方法一:synchronized + wait/notify

public class AlternatePrint {
    private static int num = 0;
    private static final Object LOCK = new Object();

    public static void main(String[] args) {
        // 偶数线程
        new Thread(() -> {
            while (num <= 100) {
                synchronized (LOCK) {
                    if (num % 2 == 0) {
                        System.out.println(Thread.currentThread().getName() + ": " + num++);
                        LOCK.notify();
                    } else {
                        try { LOCK.wait(); } catch (InterruptedException ignored) {}
                    }
                }
            }
        }, "偶数").start();

        // 奇数线程
        new Thread(() -> {
            while (num <= 100) {
                synchronized (LOCK) {
                    if (num % 2 == 1) {
                        System.out.println(Thread.currentThread().getName() + ": " + num++);
                        LOCK.notify();
                    } else {
                        try { LOCK.wait(); } catch (InterruptedException ignored) {}
                    }
                }
            }
        }, "奇数").start();
    }
}

必须用 while 而不是 if

wait() 被唤醒后需要重新检查条件,防止"虚假唤醒"(spurious wakeup)。这是 JDK Object.wait() 文档的明确建议。

方法二:Lock + Condition(更清晰)

Lock lock = new ReentrantLock();
Condition even = lock.newCondition();
Condition odd  = lock.newCondition();

// 偶数线程
lock.lock();
try {
    while (num % 2 != 0) even.await();
    System.out.println("偶数: " + num++);
    odd.signal();
} finally { lock.unlock(); }

方法三:两个线程用 TransferQueue / Exchanger

更现代的写法是用 Exchanger<Integer>,但题面要求"两个线程",wait/notify 最经典。

方法四:Semaphore

Semaphore semEven = new Semaphore(1);
Semaphore semOdd  = new Semaphore(0);

// 偶数线程
semEven.acquire();
System.out.println(num++);
semOdd.release();

面试加分

  • 答出 wait 必须在 synchronized 块内、会释放锁。
  • 答出 notify 只是唤醒,不释放锁(要等 synchronized 块结束才释放)。
  • 推荐用 Condition 替代,因为可以精确唤醒特定线程,避免"惊群"。