Java线程与三个线程的协作打印额外的数字



我正试图通过三个线程打印三个AP序列(以3为增量(,如下所示:

  • 线程1正在打印序列1, 4, 7, 10, ...
  • 线程-2正在打印序列2, 5, 8, ...
  • Thread-3正在打印序列3, 6, 9, ...

当其他线程轮流打印序列号时,线程应该等待。线程应相互协作,按从1到LIMIT(整数;此处LIMIT=10(的顺序打印数字。

预期输出

(限值=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)

实际输出

(限值=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();
}
}

该程序有三种不同的同步方法:printAPStartingFrom1()printAPStartingFrom2()printAPStartingFrom3(),分别由线程1、线程2和线程3调用。线程使用wait()notifyAll()方法相互协作。

为什么输出总是涉及两个额外的数字,它们超过了给定的10的极限,即11和12?

当线程被唤醒时(wait->runnable(,它需要再次判断当前的counter是否小于LIMIT,否则,它将继续打印,直到while (counter <= LIMIT)不成立。(这就是为什么也打印1112的原因(。

我建议您提前确定每个线程将循环多少次(这将使代码更简单(:

// 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();
}
}