Java 多线程交替打印

学习多线程最好的方法就是敲代码了,可以通过练习几个简单的 Demo 来理解 Java 中的多线程之间的协同工作。

Demo 1:交替打印数值

使用两个线程交替打印数值到 100,也就是说线程A打印1,然后线程B打印2,接着再线程A打印3,……,最后线程B打印100

首先实现一个 Runnable 类:

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
public class Print implements Runnable {

private static int i = 1;

@Override
public void run() {
while (true) {
synchronized (this) {
notify();
if (i <= 100) {
System.out.println(Thread.currentThread().getName() + " print: " + i);
++i;

try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
}
}
}
}

接着创建线程进行调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
Print print = new Print();
Thread threadOne = new Thread(print);
threadOne.setName("Thread 1");
Thread threadTwo = new Thread(print);
threadTwo.setName("Thread 2");

threadOne.start();
threadTwo.start();
}

// 运行结果
// Thread 1 print: 1
// Thread 2 print: 2
// Thread 1 print: 3
// Thread 2 print: 4
// Thread 1 print: 5
// Thread 2 print: 6
// ···
// ···

Demo 2:交替打印ABC

使用三个线程交替打印A、B、C,也就是说线程1打印A,然后线程2打印B,接着线程3打印C。和Demo 1 不同的是,现在需要 3 个线程进行协作,因此所需要的对象锁的数量也会增加。

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
public class Print implements Runnable {

private final String name;
private final Object prev; // 前一个对象,比如当打印B时就为A
private final Object self; // 当前对象

public Print(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}

@Override
public void run() {
int count = 10; // 每个字母打印的次数
while (count > 0) {
synchronized (prev) {
synchronized (self) {
System.out.println("Now printing: " + name);
--count;
self.notify();
}

try {
if (count == 0) {
prev.notify();
} else {
prev.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

创建线程并启动:

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
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();

Print printA = new Print("A", c, a);
Print printB = new Print("B", a, b);
Print printC = new Print("C", b, c);

new Thread(printA).start();
Thread.sleep(100);
new Thread(printB).start();
Thread.sleep(100);
new Thread(printC).start();

}

// Result:
//
// Now printing: A
// Now printing: B
// Now printing: C
// Now printing: A
// Now printing: B
// Now printing: C
// ···
// ···

除了使用 synchronized 关键字和对象自带的 wait() 与 notify() 方法来实现外,还可以使用 JUC 包下的 Lock 锁以及 Condition 来实现。

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public class PrintUseLock {

private static final Lock lock = new ReentrantLock();
private static final Condition A = lock.newCondition();
private static final Condition B = lock.newCondition();
private static final Condition C = lock.newCondition();

private static int count = 0;

static class ThreadA extends Thread {
@Override
public void run() {
try {
lock.lock();
for (int i = 0; i < 10; i++) {
while (count % 3 != 0) {
A.await();
}
System.out.println("Now printing: A");
count++;
B.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

static class ThreadB extends Thread {
@Override
public void run() {
try {
lock.lock();
for (int i = 0; i < 10; i++) {
while (count % 3 != 1) {
B.await();
}
System.out.println("Now printing: B");
count++;
C.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

static class ThreadC extends Thread {
@Override
public void run() {
try {
lock.lock();
for (int i = 0; i < 10; i++) {
while (count % 3 != 2) {
C.await();
}
System.out.println("Now printing: C");
count++;
A.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}

Java 多线程交替打印
https://uponclouds.top/2025/07/15/Java多线程交替打印/
作者
Gentle He
发布于
2025年7月15日
许可协议