我是多線程新手,瞭解wait,notify和notifyAll的功能。我想要三個線程一個接一個地執行並打印從A到Z的字母。 我嘗試了下面的代碼,它似乎也在工作,但我懷疑這是否是解決問題的最佳方法。有沒有其他辦法,我可以讓它更簡單更好?似乎我的代碼的一部分正在重複。如何在多線程下編寫最佳方式
package demo.threading;
class Flags {
boolean flagA = true;
boolean flagB = false;
boolean flagC = false;
}
class Container {
Flags flags = new Flags();
int charVal = (int) 'A';
void producer1() {
try {
while (charVal <= (int) 'Z') {
synchronized (this) {
if (!flags.flagA)
wait();
else {
System.out.println(Thread.currentThread().getName() + " Produced : " + (char) charVal);
flags.flagA = false;
flags.flagB = true;
charVal++;
notifyAll();
Thread.sleep(1000);
}
}
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void producer2() {
try {
while (charVal <= (int) 'Z') {
synchronized (this) {
if (!flags.flagB)
wait();
else {
System.out.println(Thread.currentThread().getName() + " Produced : " + (char) charVal);
flags.flagB = false;
flags.flagC = true;
charVal++;
notifyAll();
Thread.sleep(1000);
}
}
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void producer3() {
try {
while (charVal <= (int) 'Z') {
synchronized (this) {
if (!flags.flagC)
wait();
else {
System.out.println(Thread.currentThread().getName() + " Produced : " + (char) charVal);
flags.flagC = false;
flags.flagA = true;
charVal++;
notifyAll();
Thread.sleep(1000);
}
}
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
Container container = new Container();
Thread t1 = new Thread(() -> container.producer1(), "Thread 1");
Thread t2 = new Thread(() -> container.producer2(), "Thread 2");
Thread t3 = new Thread(() -> container.producer3(), "Thread 3");
t1.start();
t2.start();
t3.start();
}
}
輸出應該是:
Thread 1 Produced : A
Thread 2 Produced : B
Thread 3 Produced : C
Thread 1 Produced : D
Thread 2 Produced : E
Thread 3 Produced : F
打印的字母三次,最好的辦法是'的System.out.println(「ABC ... XYZABC。 ..XYZABC ... XYZ「)';或者你試圖實現的任何順序。嘗試從這樣的例子中學習多線程的問題是,他們根本不需要多線程。 –
此外,這個例子有點沒有道理:'wait'應該在循環中使用 - **「在一個參數版本中,中斷和虛假喚醒是可能的,並且該方法應該總是在循環中使用」* *來自[JavaDoc](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait--)您的catch-block只會結束該線程,因此無法處理虛假的中斷正確。 – Fildor
@Fildor,嗨,感謝您的反饋,您可以請建議任何更合理的方式來實現相同:) –