1. 程式人生 > >一篇關於執行緒併發的簡單案例

一篇關於執行緒併發的簡單案例

之前對執行緒併發的理解不夠深刻,寫一個簡單案例體會一下

如題

/**
 * sleep 是執行緒類(Thread)的方法,導致此執行緒暫停執行指定時間,
 * 給執行機會給其他執行緒,但是監控 狀態依然保持,到時後會自動恢復。
 * 呼叫 sleep 不會釋放物件鎖。wait 是 Object 類的方法,對此物件
 * 呼叫 wait 方法導致本執行緒放棄物件鎖,進入等待此物件的等待鎖定池,
 * 只有針對此物件發出 notify 方法(或 notifyAll)後本執行緒才進入對
 * 象鎖定池準備獲得對 象鎖進入執行狀態。
 * 
 * sleep:導致此執行緒暫停執行指定時間;
stop:這個方法將終止所有未結束的方法,包括 run 方法;
wait:當前正在被服務的執行緒需要睡一會,醒來後繼續被服務。
 * @author cheng
 *
 */
public class Test02 {
public static void main(String args[]) throws InterruptedException {
Thread mThread = Thread.currentThread();
Thread t = new Thread() {
            public void run() {
            try {

                                Thread.sleep(250);//1.  這句話註釋掉和不註釋掉的區別,或者更改sleep裡面時間的區別

} catch (InterruptedException e) {
e.printStackTrace();
}
                pong();
            }
        };
        t.start();//換成t.run(),觀察不同一般在筆試題中是陷阱,混淆start
        mThread.sleep(250);//2.  這句話註釋掉和不註釋掉的區別,或者更改sleep裡面時間的區別
        System.out.print("ping");
    }
    static void pong() {
        System.out.print("pong");
    }

}

分析:

情形一:如果把註釋1(下文都用1)位置和註釋2(下文都用2)位置的程式碼註釋掉,那麼輸出為“pingpong”,首先從main方法入口順序執行程式碼,當執行緒t被啟動時,由於sleep方法都被註釋掉了,main方法執行緒(mthread)和t執行緒(t)不會存在暫停並給其他執行緒讓出cpu時間這一說。那麼在t被啟動瞬間,由於mthread還佔用這cpu時間,所以會將後面的程式碼執行完成後輸出ping,然後mthread讓出cpu時間給t,t執行pong,最終輸出pingpong(還有一種解釋是mthread的優先順序要大於t的優先順序,不過應該不正確,畢竟mhread從頭到尾如果沒有sleep,那麼就在一直佔用cpu時間不會讓給t。如果執行緒除了sleep,wait,stop方法外還有別的途徑能自主放棄cpu時間。那麼執行緒優先順序的解釋就是正確的,這是一些猜想,希望有人能給出認證。)

情形二:如果把1的程式碼註釋掉,那麼顯然mthread會進入暫停,會讓cpu時間給t,那麼t執行輸出pong。t執行緒完成任務被殺死,mthread接收cpu時間執行ping,最終結果輸出pongping

情形三:如果1,2處程式碼都保留,並且裡面的時間都寫成250毫秒的話,那麼有機率輸出pingpong,也有機率輸出pongping。

我們再從main介面跟著mthread順序執行main方法內部的程式碼,當t.start()後,t被啟動,這時候mthread進入暫停,然後cpu時間會分配給t,執行t內的run方法,然後t也被暫停。雖然從暫停上來看,mthread和t存在先後,mthread再前,但是這兩個執行緒的暫停方法之間的時間可以忽略不計,為無窮小。那麼從這方面分析,兩個執行緒會同時醒來,這時候就看cpu給哪個執行緒分配時間了,如果是mthread那麼顯然輸出pingpong,如果是t,顯然輸出pongping