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());
                }
            }
        }
    }

}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 相关概念 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对...
    东经315度阅读 2,005评论 0 8
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,150评论 0 8
  • 1.解决信号量丢失和假唤醒 public class MyWaitNotify3{ MonitorObject m...
    Q罗阅读 917评论 0 1
  • 本文出自 Eddy Wiki ,转载请注明出处:http://eddy.wiki/interview-java.h...
    eddy_wiki阅读 2,248评论 0 14
  • 说到今年冬天的流行色,无外乎就想到暖到心里的焦糖色,不管是大衣、裙子,还是围巾、靴子这些单品,穿在身上都会散发出甜...
    昌乐全福元ddm朱雪萍阅读 488评论 1 0