斐訊面試記錄—三線程交替打印ABC


 

package cn.shenzhen.feixun;

public class PrintABC extends Thread{
    private String name;
    private Object prev;
    private Object self;
    
    
    public PrintABC(String name,Object prev,Object self){
        this.name=name;
        this.prev=prev;
        this.self=self;
    }
    /**
     * ,為了控制執行的順序,必須要先持有prev鎖,
     * 也就是前一個線程要釋放自身對象鎖,再去申請自身對象鎖,兩者兼備時打印字母,
     * 之后首先調用self.notify()釋放自身對象鎖,喚醒下一個等待線程,
     * 再調用prev.wait()釋放prev對象鎖,終止當前線程,等待循環結束后再次被喚醒。
     * 程序運行的主要過程就是A線程最先運行,持有C,A對象鎖,后釋放A,C鎖,喚醒B。
     * 線程B等待A鎖,再申請B鎖,后打印B,再釋放B,A鎖,喚醒C,線程C等待B鎖,再申請C鎖,
     * 后打印C,再釋放C,B鎖,喚醒A……
     */
    public void run(){
        int count=0;
        while(count<10){
            // 先獲取 prev鎖 如此問題中先將對象C鎖住
            synchronized (prev) {
                //然后獲取自身的鎖如此問題中將對象A鎖住
                synchronized (self) {
                    System.out.print(name+"");
                    count++;
                    self.notify();//此問題中一共有三個對象ABC此時將self喚醒,是其他線程來競爭self
                }
                try {
                    prev.wait();
                    /**
                     * 注意的是notify()調用后,並不是馬上就釋放對象鎖,
                     * 而是在相應的synchronized(){}語句塊執行結束,自動釋放鎖,
                     * JVM會在wait()對象鎖的線程中隨機選取一線程,賦予其對象鎖,喚醒線程,繼續執行。 
                     */
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Object a=new Object();
        Object b=new Object();
        Object c=new Object();
        
        PrintABC printA=new PrintABC("A", c, a);//第一個線程先將AC對象鎖住,A執行完了之后釋放鎖
        PrintABC printB=new PrintABC("B", a, b);
        PrintABC printC=new PrintABC("C", b, c);
        
        /**
         * 為了避免JVM啟動ThreadA、ThreadB、ThreadC三個線程順序的不確定性。
         * 需要讓A,B,C三個線程以確定的順序啟動,中間加一段sleep確保前一個線程已啟動。
         */
        printA.start();
        /**
         * sleep()方法導致了當前線程暫停執行指定的時間,
         * 讓出cpu該其他線程,但是他的監控狀態依然保持者,
         * 當指定的時間到了又會自動恢復運行狀態。
         */
        printA.sleep(10);
        printB.start();
        printB.sleep(10);
        printC.start();
        printC.sleep(10);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM