Java 与三个线程的线程合作打印额外的数字
Java Thread Cooperation with Three Threads Prints Extra Numbers
我正在尝试通过三个线程打印三个 AP 序列(以 3 为增量),如下所示:
- 线程 1 正在打印序列
1, 4, 7, 10, ...
- 线程 2 正在打印序列
2, 5, 8, ...
- 线程 3 正在打印序列
3, 6, 9, ...
当任何其他线程轮流打印它们的序列号时,一个线程应该等待。线程应相互协作以从 1 到 LIMIT(整数;此处 LIMIT = 10)按顺序打印数字。
预期输出
(对于 LIMIT = 10)
1 (printed by Thread-1)
2 (printed by Thread-2)
3 (printed by Thread-3)
4 (printed by Thread-1)
5 (printed by Thread-2)
6 (printed by Thread-3)
7 (printed by Thread-1)
8 (printed by Thread-2)
9 (printed by Thread-3)
10 (printed by Thread-1)
实际输出
(对于 LIMIT = 10)
1 (printed by Thread-1)
2 (printed by Thread-2)
3 (printed by Thread-3)
4 (printed by Thread-1)
5 (printed by Thread-2)
6 (printed by Thread-3)
7 (printed by Thread-1)
8 (printed by Thread-2)
9 (printed by Thread-3)
10 (printed by Thread-1)
11 (printed by Thread-2)
12 (printed by Thread-3)
代码
class PrintingSequences {
private static final int LIMIT = 10;
int counter = 1;
boolean isPrinting = false;
// prints 1, 4, 7, 10, ...
synchronized void printAPStartingFrom1() {
while (counter <= LIMIT) {
while (isPrinting || counter % 3 != 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e);
Thread.currentThread().interrupt();
}
}
isPrinting = true;
System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
isPrinting = false;
notifyAll();
}
}
// prints 2, 5, 8, 11, ...
synchronized void printAPStartingFrom2() {
while (counter <= LIMIT) {
while (isPrinting || counter % 3 != 2) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e);
Thread.currentThread().interrupt();
}
}
isPrinting = true;
System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
isPrinting = false;
notifyAll();
}
}
// prints 3, 6, 9, 12, ...
synchronized void printAPStartingFrom3() {
while (counter <= LIMIT) {
while (isPrinting || counter % 3 != 0) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e);
Thread.currentThread().interrupt();
}
}
isPrinting = true;
System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
isPrinting = false;
notifyAll();
}
}
}
public class TripleThreadCommunication {
public static void main(String[] args) {
PrintingSequences naturalNumbers = new PrintingSequences();
new Thread("Thread-1") {
@Override
public void run() {
naturalNumbers.printAPStartingFrom1();
}
}.start();
new Thread("Thread-2") {
@Override
public void run() {
naturalNumbers.printAPStartingFrom2();
}
}.start();
new Thread("Thread-3") {
@Override
public void run() {
naturalNumbers.printAPStartingFrom3();
}
}.start();
}
}
程序有3个不同的synchronized方法:printAPStartingFrom1()
、printAPStartingFrom2()
、printAPStartingFrom3()
,分别被Thread-1、Thread-2、Thread-3调用。线程使用 wait()
和 notifyAll()
方法相互协作。
为什么输出始终包含两个超过给定限制 10 的额外数字,即 11 和 12?
线程被唤醒时(wait
->runnable
),需要重新判断当前counter
是否小于LIMIT
,否则,它将继续打印直到 while (counter <= LIMIT)
不成立。(这就是 11
和 12
也被打印的原因)。
我建议你提前确定每个线程循环多少次(这样可以使代码更简单):
// thread1
// prints 1, 4, 7, 10, ...
synchronized void printAPStartingFrom1() {
int count = LIMIT % 3 == 0 ? LIMIT / 3 : LIMIT / 3 + 1;
for (int i = 0; i < count; i++) {
while (counter % 3 != 1) {
wait();
}
printAndAddCounter();
notifyAll();
}
}
// thread2
// prints 2, 5, 8, 11, ...
synchronized void printAPStartingFrom1() {
int count = (LIMIT - 1) % 3 == 0 ? LIMIT / 3 : LIMIT / 3 + 1;
for (int i = 0; i < count; i++) {
while (counter % 3 != 2) {
wait();
}
printAndAddCounter();
notifyAll();
}
}
// thread3
// prints 3, 6, 9, 12, ...
synchronized void printAPStartingFrom1() {
int count = LIMIT / 3;
for (int i = 0; i < count; i++) {
while (counter % 3 != 0) {
wait();
}
printAndAddCounter();
notifyAll();
}
}
我正在尝试通过三个线程打印三个 AP 序列(以 3 为增量),如下所示:
- 线程 1 正在打印序列
1, 4, 7, 10, ...
- 线程 2 正在打印序列
2, 5, 8, ...
- 线程 3 正在打印序列
3, 6, 9, ...
当任何其他线程轮流打印它们的序列号时,一个线程应该等待。线程应相互协作以从 1 到 LIMIT(整数;此处 LIMIT = 10)按顺序打印数字。
预期输出
(对于 LIMIT = 10)
1 (printed by Thread-1)
2 (printed by Thread-2)
3 (printed by Thread-3)
4 (printed by Thread-1)
5 (printed by Thread-2)
6 (printed by Thread-3)
7 (printed by Thread-1)
8 (printed by Thread-2)
9 (printed by Thread-3)
10 (printed by Thread-1)
实际输出
(对于 LIMIT = 10)
1 (printed by Thread-1)
2 (printed by Thread-2)
3 (printed by Thread-3)
4 (printed by Thread-1)
5 (printed by Thread-2)
6 (printed by Thread-3)
7 (printed by Thread-1)
8 (printed by Thread-2)
9 (printed by Thread-3)
10 (printed by Thread-1)
11 (printed by Thread-2)
12 (printed by Thread-3)
代码
class PrintingSequences {
private static final int LIMIT = 10;
int counter = 1;
boolean isPrinting = false;
// prints 1, 4, 7, 10, ...
synchronized void printAPStartingFrom1() {
while (counter <= LIMIT) {
while (isPrinting || counter % 3 != 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e);
Thread.currentThread().interrupt();
}
}
isPrinting = true;
System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
isPrinting = false;
notifyAll();
}
}
// prints 2, 5, 8, 11, ...
synchronized void printAPStartingFrom2() {
while (counter <= LIMIT) {
while (isPrinting || counter % 3 != 2) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e);
Thread.currentThread().interrupt();
}
}
isPrinting = true;
System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
isPrinting = false;
notifyAll();
}
}
// prints 3, 6, 9, 12, ...
synchronized void printAPStartingFrom3() {
while (counter <= LIMIT) {
while (isPrinting || counter % 3 != 0) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e);
Thread.currentThread().interrupt();
}
}
isPrinting = true;
System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
isPrinting = false;
notifyAll();
}
}
}
public class TripleThreadCommunication {
public static void main(String[] args) {
PrintingSequences naturalNumbers = new PrintingSequences();
new Thread("Thread-1") {
@Override
public void run() {
naturalNumbers.printAPStartingFrom1();
}
}.start();
new Thread("Thread-2") {
@Override
public void run() {
naturalNumbers.printAPStartingFrom2();
}
}.start();
new Thread("Thread-3") {
@Override
public void run() {
naturalNumbers.printAPStartingFrom3();
}
}.start();
}
}
程序有3个不同的synchronized方法:printAPStartingFrom1()
、printAPStartingFrom2()
、printAPStartingFrom3()
,分别被Thread-1、Thread-2、Thread-3调用。线程使用 wait()
和 notifyAll()
方法相互协作。
为什么输出始终包含两个超过给定限制 10 的额外数字,即 11 和 12?
线程被唤醒时(wait
->runnable
),需要重新判断当前counter
是否小于LIMIT
,否则,它将继续打印直到 while (counter <= LIMIT)
不成立。(这就是 11
和 12
也被打印的原因)。
我建议你提前确定每个线程循环多少次(这样可以使代码更简单):
// thread1
// prints 1, 4, 7, 10, ...
synchronized void printAPStartingFrom1() {
int count = LIMIT % 3 == 0 ? LIMIT / 3 : LIMIT / 3 + 1;
for (int i = 0; i < count; i++) {
while (counter % 3 != 1) {
wait();
}
printAndAddCounter();
notifyAll();
}
}
// thread2
// prints 2, 5, 8, 11, ...
synchronized void printAPStartingFrom1() {
int count = (LIMIT - 1) % 3 == 0 ? LIMIT / 3 : LIMIT / 3 + 1;
for (int i = 0; i < count; i++) {
while (counter % 3 != 2) {
wait();
}
printAndAddCounter();
notifyAll();
}
}
// thread3
// prints 3, 6, 9, 12, ...
synchronized void printAPStartingFrom1() {
int count = LIMIT / 3;
for (int i = 0; i < count; i++) {
while (counter % 3 != 0) {
wait();
}
printAndAddCounter();
notifyAll();
}
}