/*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 ; } }