紅色的表示主線程的while(){}代碼塊,
藍色的表示子線程的異常執行,
黑色的表示子線程代碼段:j++;的執行;
#爲什麼產生異常#java.lang.InterruptException#當父線程(外部線程)的sleep時間小於子線程的sleep時間,程序就會出現異常,但是並不影響程序的執行(可能因爲try-catch吧)。
當你不想看到異常時,可以把外部線程(DemoFather)第一次sleep的時間改成大於內部線程的sleep時間即可消除異常。
public class DemoFather {
public static void main(String[] args) {
InThreaad inThread =new InThreaad();
Thread outThread = new Thread(inThread);
System.out.println("DemoFather線程調用start方法之前的狀態:" + outThread.getState());
outThread.start();
System.out.println("DemoFather線程調用start方法之後的狀態:" + outThread.getState());
try {
Thread.sleep(100); //當父線程(outThread線程/DemoFather線程)的sleep時間100 < 子線程(inThread/子線程)
//sleep時間500時,inThread會因爲outThread執行了interrupt方法,進而產生java.lang.InterruptException。
} catch (InterruptedException e) {
e.printStackTrace();
} //該sleep的作用是爲了證明interrupt終止的作用(事實上,它只是起到了喚醒子線程的作用)。
inThread.printData();//打印出內部InThread的synchronized前一半;
outThread.interrupt(); //喚醒子線程,CPU調度去執行內部線程“未完成的部分”(synchronized的另一半)。
while (outThread.isAlive()) {
//主線程等待子線程執行完synchronized內的代碼;
inThread.printData();
}
inThread.printData();
System.out.println("通過isAlive()等待子線程的喚醒、執行,讓其執行InThread線程,:" + outThread.getState().name());
System.out.println("DemoFather線程調用interrupt方法之後:" + outThread.getState().name());
inThread.printData();
}
}
public class InThreaad implements Runnable{
int i,j;
public void run() {
System.out.println("線程Sun進入runnable狀態:" + Thread.currentThread().getState());
synchronized (this){
System.out.println("線程Sun進入synchronized狀態:" + Thread.currentThread().getState());
i++;
try {
Thread.sleep(500); //java.lang.InterruptException
//當父線程(outThread線程/DemoFather線程)的sleep時間100 < 子線程(inThread/子線程)的sleep時間500時,
//inThread會因爲outThread執行了interrupt方法,進而產生java.lang.InterruptException。
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
}
System.out.println("線程Sun進入終止狀態:" + Thread.currentThread().getState());
}
public void printData() {
System.out.println("i = " + i + "/r j = " + j);
}
}
執行截圖:
當主線程調用interrupt後,子線程將依次產生4個異常(此時的主線程不會因爲子線程的喚醒而停止執行,因爲它打印出了i,j值),隨着子線程的四個異常完成後,子線程被喚醒,繼續執行其代碼(j++;)。
-續上圖
1,2,3,4的過程表明了主線程和子線程的併發執行(通過2,3感覺主線程的執行速度比子線程的速度快啊[困惑])。
代碼執行過程描述:
程序執行入口main方法:
1.創建內部線程,inThread = new InThreaad();
2.根據inThreaad創建外部線程,outThread = new Thread(inThread);
3.依次執行main方法的代碼 -> 直到當前線程Thread(即:outThread)執行了sleep(100);
4.CPU調度跳轉執行InThreaad -> 依次執行InThread中的代碼:run(); -> 直到執行到當前線程(inThread)sleep時;
5.CPU調度跳轉執行OutThreaad線程 -> 依次執行OutThread中的代碼:printData(); -> interrupt();
6.CPU調度跳轉執行InThreaad(產生4次異常後,異常見下截圖) -> 依次執行InThread中的代碼:j++;
7.InThread線程內的方法都執行完成後,再次執行OutThread線程剩餘代碼:printData();
8.end
關於第6步:
此文如有不妥,請給予指點,感謝!