兩線程交替打印數字


定義兩個線程 交替打印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());
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM