join加入執行緒和中斷執行緒
阿新 • • 發佈:2022-04-08
join方法存在於Thread類中,主要作用是使原本並航執行的執行緒變為序列執行,程式碼如下:
package thread; public class Thread5 implements Runnable {//實現Runnable介面 @Override public void run() {//重寫run方法 for (int i = 0; i < 50; i++) { System.out.println("我是run執行緒" + i); } } public static void main(String[] args) { Thread5 t1 = new Thread5();//建立該類的例項物件 Thread t = new Thread(t1);//建立Thread類的例項物件,並把需要同步執行的執行緒丟進去 t.start();//啟動執行緒 for (int i = 0; i < 50; i++) { System.out.println("我是主執行緒" + i); if (i == 20) { try { t.join();//上面啟動執行緒的時候已經把分支執行緒丟進了Theard的例項裡面,所以這裡的T代表的就是主執行緒,程式碼含義為當i迴圈到20的時候,那麼分支執行緒加入進來先執行 } catch (InterruptedException e) { e.printStackTrace(); } } } } }
注意:
- join加入執行緒也會丟擲異常,需要用try catch進行捕獲
- join方法無法用於run方法中,這和程式載入順序有關
中斷執行緒:
interrupt():中斷執行緒,它只是做了一箇中斷標記,是否中斷執行緒,由執行緒本身來決定!且如果程式丟擲一個interruptedException異常,當丟擲此異常的時候,當前執行緒的中斷狀態將被清除
interrrupted():測試當前執行緒是否中斷,且該方法也會把當前執行緒的中斷狀態清除,如果這個方法被連續呼叫兩次,那麼第二次呼叫會返回false。
public class Thread6 implements Runnable { @Override public void run() { for (int i = 0; i < 50; i++) {//執行緒體 if (Thread.interrupted()){//第二步,寫一個if語句判斷該執行緒是否處於中斷狀態 break;//如果返回結果是true就退出迴圈 } System.out.println(Thread.currentThread().getName()+"--"+i); try {//sleep方法丟擲的異常會使執行緒清除中斷狀態 Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt();//第三步在catch處理異常的時候加入interrupt可以中斷執行緒 } } } public static void main(String[] args) { Thread6 t1 = new Thread6(); Thread t = new Thread(t1); t.start(); for (int i = 0; i <50 ; i++) { System.out.println(Thread.currentThread().getName()+"--"+i); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } if(i==20){ t.interrupt();//第一步,當i=20的時候就向執行緒T傳送一箇中斷標記 } } } }
程式執行過程:
類載入完畢,開始尋找Main方法,找到main方法後程序繼續執行
- 新建一個該類的例項物件,新建一個Thread類的例項物件,並把類的例項物件丟進Thread類的例項
- Thread類呼叫自身的start方法啟動多執行緒,start裡面會把重寫的run方法也加入同步執行
- 兩個執行緒開始同步執行迴圈,進入到sleep方法中開始交替休眠執行,當main執行緒進入if語句,i=20時,會給t執行緒傳送一箇中斷標記,要求t執行緒中斷執行,t執行緒進入自身的for迴圈裡面重複執行,當接收到中斷標記時,它會進入if語句退出迴圈,迴圈結束那麼t執行緒也就結束了
自定義標記中斷執行緒:
以上中斷執行緒的方式過於麻煩,我們也可以自己定義一個標記來中斷執行緒,思路如下:
- 在類裡定義一個布林型別的資料型別,初始值為true
- 在類裡面重寫構造方法flag為true
- 在main方法設定執行緒終止時機,如果迴圈到20次的時候,就把flag的值置為false,程式執行到這個時候因為它的值是false了,所以執行緒會終止進行
public class Thread7 implements Runnable{
public boolean flag = true;
public Thread7(){
flag = true;
}
public static void main(String[] args) {
Thread7 thread7 = new Thread7();
Thread t1 = new Thread(thread7);
t1.start();
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i==20){
thread7.flag = false;
}
}
}
@Override
public void run() {
int i = 0;
while (flag){
System.out.println(Thread.currentThread().getName()+i++);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}