多线程循环打印ABC

       朋友最近去公司应聘,遇到了这么一道面试题,利用多线程循环打印ABC,刚好我也在学习多线程,看了网上的一些例子,结合自己的理解,编写了一个例子,与大家一起探讨;该例子使用到synchronized(对象同步锁),wait(),notifyAll()是两个定义在Object类里的方法,可以用来控制线程的状态。

        这两个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。

  • 如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
  • 如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

实现思路:

      1、新建一个打印类PrintABC.java,处理打印ABC 业务逻辑;

      2、 新建三个线程类,分别为:PrintAThread,PrintBThread,PrintCThread分别执行打印方法;开启三个线程,每个线程一次打印一个字母(PrintAThread打印 A,PrintBThread打印B,PrintCThread打印C),并且按照一定的顺序打印,当打印A的时候,其他线程处于阻塞状态,打印完A以后,将线程解锁,让打印B的那个线程开启,其他线程处于阻塞状态,同理打印C的时候,阻塞其他线程,这三个线程顺序循环,就达到顺序多次打印ABC的目的了

打印类PrintABC.java

class PrintABC {
    private boolean printAThread = true;
    private boolean printBThread = false;
    private boolean printCThread = false;

    public void excute() {
        synchronized (this) {
            while (!printAThread) {
                try {
                    wait();
                } catch (InterruptedException e) {                    
                    e.printStackTrace();
                }    
            }
            System.out.print("A");
            this.printAThread = false;
            this.printBThread = true;
            this.printCThread = false;            
            notifyAll();
        }

    }
    
    public void excute2() {
        synchronized (this) {
            while (!printBThread) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                }                
            }
            System.out.print("B");
            this.printAThread = false;
            this.printBThread = false;
            this.printCThread = true;
        
            notifyAll();
        }
    }    
    
    public void excute3() {
        synchronized (this) {
            while (!printCThread) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                }                
            }
            System.out.println("C");
            this.printAThread = true;
            this.printBThread = false;
            this.printCThread = false;        
            notifyAll();
        }
    }

}


线程类PrintAThread.java:

class PrintAThread extends Thread {
    private PrintABC  printABC ;

    public PrintAThread(PrintABC  printABC ) {
        this.printABC = printABC ;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            this.printABC .excute();
        }        
    }
}


线程类PrintBThread.java:

class PrintBThread extends Thread {
    private PrintABC  printABC ;

    public PrintAThread(PrintABC  printABC ) {
        this.printABC = printABC ;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            this.printABC .excute2();
        }        
    }
}

线程类PrintCThread.java:

class PrintCThread extends Thread {
    private PrintABC  printABC ;

    public PrintAThread( PrintABC  printABC ) {
        this. printABC = printABC ;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            this. printABC .excute3();
        }        
    }
}

测试类PrintABCThreadTest.java

public class PrintABCThreadTest {
    public static void main(String[] args) {
        ReaderABC readerABC = new ReaderABC();
        new PrintAThread(readerABC).start();        
        new PrintBThread(readerABC).start();
        new PrintCThread(readerABC).start();
    }
}

最终控制台打印结果如下:

多线程循环打印ABC_第1张图片

例子结束,如有错漏,请大家指出,谢谢!

备注:多线程,对象锁,线程等待, 通知相关知识都是编程比较重要的一部分,希望大家能掌握



你可能感兴趣的:(java)