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 ;
    }
}
原文地址:https://www.cnblogs.com/debug-the-heart/p/13233852.html