定義兩個線程 交替打印1~100的數,通過wait和notify實現
看到這個題目第一個想法是要控制兩個線程交替打印 與生產者消費者的架構設計模式好像有點類似 所以直接上代碼吧
public class alternateprint{ int i = 0; boolean isprintf = false; public void printf1() throws InterruptedException { while (i <= 100) { synchronized (this) { if (isprintf) { notifyAll(); System.out.println(Thread.currentThread().getName() + ":" + (i++)); isprintf = false; } else { wait(); } } } } public void printf2() throws InterruptedException { while (i <= 100) { synchronized (this) { if (!isprintf) { System.out.println(Thread.currentThread().getName() + ":" + (i++)); isprintf = true; notifyAll(); } else { wait(); } } } } public static void main(String[] args) { alternateprint alternateprint = new alternateprint(); new Thread() { @Override public void run() { try { alternateprint.printf1(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); new Thread() { @Override public void run() { try { alternateprint.printf2(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
邏輯單元很簡單 通過wait和notify來控制邏輯的實現 一個線程在打印后即使再搶到cpu的執行權 也會因為isprintf的控制位而進入wait的狀態,這樣就實現了交替打印數字的任務,在寫完看代碼想到兩個方法好像有點復雜,可以綜合到一個方法中,畢竟主要的邏輯就是一個線程在輸出后要進入wait狀態由另一個線程輸出后喚醒wait的線程,由此引出第二種寫法如下:
public class printf {
int i = 0;
public synchronized void printf() throws InterruptedException {
while (i <= 100) {
notifyAll();
System.out.println(Thread.currentThread().getName() + ":" + (i++));
wait();
}
notifyAll();//這行若不添加jvm程序將會不退出,原因在於會有一個線程判斷進入了wait狀態,而另一個線程判斷已經達到100了不會進入邏輯單元,導致另一個線程沒線程喚醒 一直在wait中 所以在循環外添加一個notify喚醒它
}
public static void main(String[] args) {
printf pr = new printf();
IntStream.range(0, 2).forEach(i->new Thread(()->{
try {
pr.printf();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start());
}
}
