java面试题-循环按顺序打印ABC

3个线程分别调用3个方法,用3个标志位控制顺序。
用AtomicInteger记录次数。
A线程打印的条件是isCDone为true,isCDone初始状态为true。
B线程打印的条件是isADone为true,如果为false时,调用wait(),线程会等待。
C线程打印的条件是isBDone为true,如果为false时,调用wait(),线程会等待。
A线程执行结束会通知其他线程,此时BC都被唤醒,竞争锁,如果C抢到锁,因为isBDone为false继续等待并通知其他线程,如果B抢到因为isADone为true,打印。
每个线程的方法打印后都会通知其他线程,并且把自己打印的条件改为false,避免多次执行。例如A线程打印的条件是isCDone为true,那么A线程打印后要把isCDone改为false。

public class PrintABC {

    public static void main(String[] args) {

        PrintObject printObject = new PrintObject(100);
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {

                printObject.printA();

            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                printObject.printB();

            }
        });
        Thread threadC = new Thread(new Runnable() {
            @Override
            public void run() {

                printObject.printC();

            }

        });
        threadC.start();
        threadB.start();
        threadA.start();

    }

    static class PrintObject {

        int n = 10;
        AtomicInteger count = new AtomicInteger(0);

        PrintObject() {
        }

        PrintObject(int n) {
            this.n = n;
        }

        boolean isADone = false;
        boolean isBDone = false;
        boolean isCDone = true;


        public void printA() {

            while (count.get() < n) {
                synchronized (this) {
                    while (!isCDone) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("A");
                    isADone = true;
                    isCDone = false;
                    count.incrementAndGet();
                    this.notifyAll();
                }
            }
        }

        public void printB() {
            while (count.get() < n) {
                synchronized (this) {
                    while (!isADone) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("B");
                    isBDone = true;
                    isADone = false;
                    this.notifyAll();
                }
            }
        }

        public void printC() {
            while (count.get() < n) {
                synchronized (this) {
                    while (!isBDone) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("C");
                    isCDone = true;
                    this.notifyAll();
                    isBDone = false;
                    System.out.println("count:: " + count.get());
                }
            }
        }
    }

}

你可能感兴趣的:(java面试题-循环按顺序打印ABC)