開啟執行緒時start()方法和run方法的呼叫
阿新 • • 發佈:2018-12-11
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()的執行是在新開啟的執行緒中