interrupt()只是改變中斷狀態(tài)而已. interrupt()不會(huì)中斷一個(gè)正在運(yùn)行的線程。這一方法實(shí)際上完成的是,,給受阻塞的線程拋出一個(gè)中斷信號(hào),, 這樣受阻線程就得以退出阻塞的狀態(tài)。更確切 的說(shuō),,如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,, 那么,它將接收到一個(gè)中斷異常(InterruptedException),,從而提早地終結(jié)被阻塞狀態(tài),。 如果線程沒(méi)有被阻塞,這時(shí)調(diào)用interrupt()將不起作用,;否則,,線程就將得到InterruptedException異常(該線程必須事先預(yù)備好處理此狀況),接著逃離阻塞狀態(tài)。 線程A在執(zhí)行sleep,wait,join時(shí),線程B調(diào)用線程A的interrupt方法,的確這一個(gè)時(shí)候A會(huì)有InterruptedException 異常拋出來(lái). 但這其實(shí)是在sleep,wait,join這些方法內(nèi)部會(huì)不斷檢查中斷狀態(tài)的值,而自己拋出的InterruptedException,。 如果線程A正在執(zhí)行一些指定的操作時(shí)如賦值,for,while,if,調(diào)用方法等,都不會(huì)去檢查中斷狀態(tài) ,所以線程A不會(huì)拋出 InterruptedException,而會(huì)一直執(zhí)行著自己的操作. 當(dāng)線程A終于執(zhí)行到wait(),sleep(),join()時(shí),才馬上會(huì)拋出 InterruptedException. 若沒(méi)有調(diào)用sleep(),wait(),join()這些方法,即沒(méi)有在線程里自己檢查中斷狀態(tài)自己拋出InterruptedException的 話, 那InterruptedException是不會(huì)被拋出來(lái)的. 具體使用見(jiàn)實(shí)例1,,實(shí)例2,。 注意1:當(dāng)線程A執(zhí)行到wait(),sleep(),join()時(shí),拋出InterruptedException后,,中斷狀態(tài)已經(jīng)被系統(tǒng)復(fù)位了, 線程A調(diào)用Thread.interrupted()返回的是false public static boolean interrupted ()Since: API Level 1Returns a Returns
public boolean isInterrupted ()Since: API Level 1Returns a Returns
線程A正在使用sleep()暫停著: Thread.sleep(100000); 如果要取消他的等待狀態(tài),可以在正在執(zhí)行的線程里(比如這里是B)調(diào)用 a.interrupt(); 令線程A放棄睡眠操作,這里a是線程A對(duì)應(yīng)到的Thread實(shí)例 當(dāng)在sleep中時(shí) 線程被調(diào)用interrupt()時(shí),就馬上會(huì)放棄暫停的狀態(tài).并拋出InterruptedException.丟出異常的,是A線程. 2. wait() & interrupt() 線程A調(diào)用了wait()進(jìn)入了等待狀態(tài),也可以用interrupt()取消. 不過(guò)這時(shí)候要小心鎖定的問(wèn)題.線程在進(jìn)入等待區(qū),會(huì)把鎖定解除,當(dāng)對(duì)等待中的線程調(diào)用interrupt()時(shí) ,會(huì)先重新獲取鎖定,再拋出異常.在獲取鎖定之前,是無(wú)法拋出異常的. 3. join() & interrupt() 當(dāng)線程以join()等待其他線程結(jié)束時(shí),當(dāng)它被調(diào)用interrupt(),,它與sleep()時(shí)一樣, 會(huì)馬上跳到catch塊里. 注意,,是對(duì)誰(shuí)調(diào)用interrupt()方法,一定是調(diào)用被阻塞線程的interrupt方法.如在線程a中調(diào)用來(lái)線程t.join(). 則a會(huì)等t執(zhí)行完后在執(zhí)行t.join后的代碼,當(dāng)在線程b中調(diào)用來(lái) a.interrupt()方法,則會(huì)拋出InterruptedException,當(dāng)然join()也就被取消了,。 實(shí)例1: static void interruptDemo() { Thread t1=new Thread(new InterruptDemoRunnable(),"first"); Thread t2=new Thread(new InterruptDemoRunnable(t1),"second"); t1.start(); t2.start(); } class InterruptDemoRunnable implements Runnable { long id=0; static long count=0; Thread t; InterruptDemoRunnable() { this(null); } InterruptDemoRunnable(Thread t) { id=count ; this.t=t; } boolean blRun=true; public void run() { int cnt=0; while(blRun) { if(t!=null) { if(cnt==2) { t.interrupt(); if(t.isInterrupted()) System.out.println("set the thread " t.getName() " to be Interrupted"); } } else { try { Thread.sleep(1000); } catch(InterruptedException e) { System.out.println("First Interrupted when sleep"); System.out.println( "Interrupted is " Thread.interrupted());//@1 } try { Thread.sleep(1); } catch(InterruptedException e) { System.out.println("second Interrupted when sleep"); } } System.out.println(id "run" cnt); cnt ; if(cnt==5) { blRun=false; } } System.out.println("thread:" id "exit"); } } 注意1:當(dāng)線程A執(zhí)行到wait(),sleep(),join()時(shí),拋出InterruptedException后,,中斷狀態(tài)已經(jīng)被系統(tǒng)復(fù)位了。 線程AThread.interrupted()返回的是false 實(shí)例2: static void interruptDemo() { Thread t1=new InterruptDemoThread(); t1.setName("t1"); Thread t2=new InterruptDemoThread(t1); t1.setName("t2"); t1.start(); t2.start(); } class InterruptDemoThread extends Thread { long id=0; static long count=0; Thread t; InterruptDemoThread() { this(null); } InterruptDemoThread(Thread t) { id=count ; this.t=t; } boolean blRun=true; public void run() { int cnt=0; while(blRun) { if(t!=null) { if(cnt==2) { t.interrupt(); if(t.isInterrupted()) System.out.println("set the thread " t.getName() " to be Interrupted"); } } else if(isInterrupted())@1 { /*Thread.interrupted();//@2 System.out.println("after interrupted(),the state of Interrupted is " isInterrupted());*/ try{ Thread.sleep(1); } catch(InterruptedException e) { System.out.println("Interrupted when sleep"); System.out.println( "Interrupted is " Thread.interrupted()); } } Thread.yield(); System.out.println(id "run" cnt); cnt ; if(cnt==5) { blRun=false; } } System.out.println("thread:" id "exit"); } } 注意1:如果線程被調(diào)用了interrupt(),,那么如果此次該線程并不在wait(),sleep(),join()時(shí),, 下次執(zhí)行wait(),sleep(),join()時(shí),一樣會(huì)拋出InterruptedException,,當(dāng)然拋出后該線程的中斷狀態(tài)也回被系統(tǒng)復(fù)位,。 注意2:我們可以手動(dòng)的使用Thread.interrupted()來(lái)使當(dāng)前線程的中斷狀態(tài)系統(tǒng)復(fù)位(即清除中斷狀態(tài)) |
|
來(lái)自: 印度阿三17 > 《開(kāi)發(fā)》