多线程按顺序打印奇偶数

看到一题目“多线程按顺序打印奇偶数”,网上的做法是通过synchronized,wait,notify来实现,其实现存在bug,奇偶线程需按顺序启动,不然打印的数不正确。我通过lock和condition也实现了一个,做到可以启动多个奇数线程和多个偶数线程也能按一定的顺序打印。

public static void main(String[] args) {
        final NumberPrinter numberPrinter = new NumberPrinter();

        Thread t1 = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    numberPrinter.printNum(true);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    numberPrinter.printNum(false);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        Thread t3 = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    numberPrinter.printNum(false);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        t1.start();
        t2.start();
        t3.start();

        try {
            Thread.sleep(9000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t1.interrupt();
        t2.interrupt();
        t3.interrupt();
    }

class NumberPrinter {
    private final Lock lock = new ReentrantLock();
    private final Condition oddNumCon = lock.newCondition();
    private final Condition eventNumCon = lock.newCondition();
    private volatile int num = 0;

    public void printNum(boolean isOddNum) throws InterruptedException {
        lock.lock();
        try {
            if (isOddNum) {
                while (num % 2 == 0) {
                    //奇数等待
                    oddNumCon.await();
                }
            } else {
                while (num % 2 == 1) {
                  //偶数等待
                    eventNumCon.await();
                }
            }

            Thread.sleep(500L);
            System.out.println(Thread.currentThread().getName() + " say:" + num++);

            if (isOddNum) {
                //唤醒偶数
                eventNumCon.signal();
            } else {
                //唤醒奇数
                oddNumCon.signal();
            }

        } finally {
            lock.unlock();
        }
    }
}

你可能感兴趣的:(多线程按顺序打印奇偶数)