JAVA中使用線程交替打印奇偶數


/*2. 創建2個線程,打印從0到99這100個數字,要求線程交叉順序打印。
比如
線程1: 0
線程2: 1
線程1: 2
線程2: 3
線程1: 4
線程2: 5
注意,要求使用線程間通信的方式實現,即你打印一個數字,我打印一個數字,一直打印到99*/
package practiceagagin;

public class Test {
    //private static Object OddTask;

    public static void main(String args[]){
        PrintNumber printNum = new PrintNumber(100);
        EvenTask evenTask = new EvenTask(printNum);
        OddTask oddTask = new OddTask(printNum);
        Thread thread1 = new Thread(evenTask);
        Thread thread2 = new Thread(oddTask);
        thread1.start();
        thread2.start();
    }
}

package practiceagagin;

public class PrintNumber {
    protected int upBound;//定義打印數字的上界
    protected int currentNum=0;
    public PrintNumber(int upBound){
        this.upBound = upBound;
    }
    public int getNum(){
        return currentNum;
    }
}
package practiceagagin;

//這個類的作用是方便代碼重用,減少代碼量
//因為無論是打印奇數,還是打印偶數,他們的工作流程可以看作是一樣的
//看打印機有沒有在使用,有的話阻塞自己
//看打印機有沒有在使用,沒有的話,看是否是自己可以打印的數;是則打印-打印結束喚醒其它進程;不是則阻塞自己(這里不用去喚醒了,阻塞后又怎么能喚醒別人呢?);
//數字奇偶的判斷,交給數字類來完成;數字類也一樣提高了程序的代碼質量
abstract class PrintTask implements Runnable {
    protected PrintNumber printNum;

    public PrintTask(PrintNumber printNum) {
        this.printNum = printNum;
    }

    @Override
    public void run() {
        while (printNum.currentNum < printNum.upBound) {//還沒到達上界持續打印
            //打印操作,使用打印機需要上鎖,通過原子操作控制同步
            synchronized (printNum) {//查看打印機有沒有在使用;有的話,其它線程阻塞在外面
                //沒有,既可以打印
                //查看自己是否可以打印
                if (isShouldPrint()) {
                    System.out.println(Thread.currentThread().getName()+"打印了"+printNum.getNum());
                    printNum.currentNum++;
                    printNum.notifyAll();

                } else {
                    try {
                        printNum.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public abstract boolean isShouldPrint();

}
package practiceagagin;

public class EvenTask extends PrintTask {
    //子類繼承,也要定義下構造方法!
    public EvenTask(PrintNumber printNum) {
        super(printNum);
    }

    public boolean isShouldPrint(){
        return printNum.currentNum%2==0 ;
    }
}
package practiceagagin;

public class OddTask extends PrintTask {
    public OddTask(PrintNumber printNum){
        super(printNum);
    }
    public boolean isShouldPrint(){
        return printNum.currentNum%2!=0 ;
    }
}

 


免責聲明!

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



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