1. 程式人生 > >開啟執行緒時start()方法和run方法的呼叫

開啟執行緒時start()方法和run方法的呼叫

1、Thread類中start()的定義:

public synchronized void start() {

	if (threadStatus != 0)
		throw new IllegalThreadStateException();

	group.add(this);

	boolean started = false;
	try {
		start0();
		started = true;
	} finally {
		try {
			if (!started) {
				group.threadStartFailed(this);
			}
		} catch (Throwable ignore) {

		}
	}
}

可以看出來start()是一個同步方法,也就是說下次再呼叫同一個執行緒的start()時要等到該執行緒的上一個start()執行完之後才會被呼叫,而且該方法首先就判斷了執行緒的狀態是不是就緒,若不是則直接丟擲異常,但每一個執行緒在呼叫完start()後其執行緒狀態就會變為執行中,因此每個執行緒的start()只能被呼叫一次

2、start()和run()的執行

例子:

public class MyThread implements Runnable {

	private Integer ticket = 100;
	private static final Logger LOGGER = LoggerFactory.getLogger(MyThread.class);

	@Override
	public void run() {
		while (ticket > 0) {
			try {
				Thread.sleep(1000);
				LOGGER.error("當前票數:" + ticket);
				ticket--;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}
public static void main(String args[]) {
	MyThread mt = new MyThread();
	Thread t1 = new Thread(mt);
	t1.start();
	t1.start();
}

該段程式碼中執行緒t1的start()被呼叫了兩次,根據1中的說明肯定會丟擲IllegalThreadStateException異常,我的疑問是:根據執行列印的結果,為什麼會先丟擲IllegalThreadStateException異常,而後執行完MyThread的run(),而不是先執行完MyThread的run()之後由於t1的start()被再次呼叫而丟擲異常呢?因為start()是synchronized的,start()的第二次呼叫應該在第一次呼叫全部執行完之後才執行呀。其實理解錯了,第一次呼叫t1.start()時會開啟一個新的執行緒,run()方法是在新開啟的執行緒中執行的,此時程式中會有兩個執行緒:主執行緒和t1執行緒,這兩個執行緒的執行是互不干擾的,第一次呼叫完t1.start()後主執行緒獲取了cpu的使用權會接著第二次呼叫t1.start(),就會丟擲異常,而此時執行在t1執行緒的run()方法還沒有執行結束,所以會先丟擲異常而後執行完run(),根本原因在於兩次呼叫start()都是在主執行緒中,而run()的執行是在新開啟的執行緒中