多线程交替打印0-100

实现思路

本质上这一题是考察对于线程等待同步机制的掌握

核心思路是:

  1. 两个线程(分别称其为打印奇数和偶数的线程)共同持有一个锁,这个锁是用来打印的,只有获取到这个锁才能进行打印。
  2. 打印奇数和偶数的线程分别先判断共享变量是奇数还是偶数
    1. 如果是符合自己当前要求的数,就打印,打印完唤醒另一个等待的线程
    2. 如果不是自己当前要求的数,就释放锁,给另一个线程打印

synchronized + wait/notify

基于JVM级别自动获取和释放锁的 synchronized + Object.wait()/Object.notify() 我们有了如下的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class MultiThreadPrint {

public static volatile int num = 0;

public static final Object PRINT_LOCK = new Object();

public static final int MAX_NUM = 100;

public static void main(String[] args) {

Thread odd = new Thread(() -> printNum(false), "odd thread");
Thread even = new Thread(() -> printNum(true), "even thread");

even.start();
odd.start();
}

private static void printNum(boolean isEven) {
while (true) {
synchronized (PRINT_LOCK) {
if (num > MAX_NUM) {
PRINT_LOCK.notify();
return;
}
boolean condition = isEven ? num % 2 == 0 : num % 2 == 1;
if (condition) {
System.out.println(Thread.currentThread().getName() + ":num=" + num++);
PRINT_LOCK.notify();
} else {
try {
PRINT_LOCK.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
}
}
}

ReentrantLock + Condition

ReentrantLock 可以看作是 synchronized 的升级版,支持的功能更多。配合 Condition 使用可以实现类似 synchronized + wait/notify 的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class MultiThreadPrintReentrantLock {

private static int num = 0;

private static final int MAX_COUNT = 100;

private static final ReentrantLock LOCK = new ReentrantLock();

private static final Condition ODD_PRINT = LOCK.newCondition();

private static final Condition EVEN_PRINT = LOCK.newCondition();


public static void main(String[] args) {
Thread evenThread = new Thread(() -> printNum(true), "evenThread");
Thread oddThread = new Thread(() -> printNum(false), "oddThread");
evenThread.start();
oddThread.start();
}

private static void printNum(boolean isEven) {
Condition signalCondition = isEven ? ODD_PRINT : EVEN_PRINT;
Condition awaitCondition = isEven ? EVEN_PRINT : ODD_PRINT;
while (true) {
LOCK.lock();
try {
if (num > MAX_COUNT) {
ODD_PRINT.signal();
EVEN_PRINT.signal();
return;
}
boolean print = isEven ? num % 2 == 0 : num % 2 == 1;
if (print) {
System.out.println(Thread.currentThread().getName() + ":num=" + num);
num++;
signalCondition.signal();
} else {
try {
awaitCondition.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
} finally {
LOCK.unlock();
}
}
}
}

多线程交替打印0-100
http://example.com/2025/09/10/多线程交替打印0-100/
作者
Noctis64
发布于
2025年9月10日
许可协议