引子
本來以爲interrupt()後,線程就立刻停止了,其實不是這樣的!!!
interrupt()通知線程應該停止
interrupt()是Thread的實例方法,它通過設置線程中斷狀態,來提示線程應該停止,真正是否停止何時停止取決於程序員;interrupt()時,如果線程在WAITING/TIMED_WAITING狀態(執行了wait()、wait(long)、join()、join(long)、sleep(long))則會清除中斷狀態,拋出InterruptedException,注不要使用stop來中止線程,此方法已不推薦使用,並會帶來狀態一致性問題。
interrupt()改變狀態
Thread a = new Thread(new Runnable() {
@Override
public void run() {
int i=0;
while(true){
System.out.println(Thread.currentThread().isInterrupted()+"--"+(++i));
}
}
});
a.start();
a.interrupt();
System.out.println("線程被中斷了");
線程被中斷了
true--1
true--2
true--3
true--4
true--5
true--6
true--7
...
可以看到,執行了interrupt()後,線程爲中斷狀態,但線程未停止。
一般的,如果接到線程終止,應該停止,如下
while(true){
if(Thread.currentThread().isInterrupted()){ // 通過判斷中止狀態來採取操作
break;
}
System.out.println(Thread.currentThread().isInterrupted()+"--"+(++i));
}
輸出結果,沒有輸出數字
線程被中斷了
waiting/timed_waiting狀態,interrupt()線程拋出異常
線程處在waiting/timed_waiting狀態,interrupt()導致目標線程拋出InterruptedException異常,並清除中斷狀態;
Thread a = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getState()+"-begin-"+Thread.currentThread().isInterrupted()); // 1
try {
Thread.sleep(2000); //7
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getState()+"-end-"+Thread.currentThread().isInterrupted()); //2
e.printStackTrace(System.out);
}
}
});
a.start(); //3
System.out.println(a.getState()+"--"+a.isInterrupted()); //4
a.interrupt(); //5
System.out.println(a.getState()+"--"+a.isInterrupted()); //6
輸出結果有好幾種情況,這是因爲多線程交替執行導致,包括但不限於以下幾種情況
這種情況的執行順序是,345612
RUNNABLE--false //
RUNNABLE--true
RUNNABLE-begin-true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$1.run(Test.java:15)
at java.lang.Thread.run(Thread.java:745)
這種情況的執行順序是,341562
RUNNABLE--false
RUNNABLE-begin-false
RUNNABLE--true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$1.run(Test.java:15)
at java.lang.Thread.run(Thread.java:745)
這種情況的執行順序是,317456,咱們重點解釋這種情況,a.start()後,接着執行a線程run方法,1輸出false,執行到7,進入timed_waiting狀態,線程切換到主線程執行4,輸出false,執行5後,線程中斷狀態爲true,繼續執行5,輸出true,調度器切換到a線程拋出異常清除中斷狀態,執行2輸出false。
RUNNABLE-begin-false
TIMED_WAITING--false
TIMED_WAITING--true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$1.run(Test.java:15)
at java.lang.Thread.run(Thread.java:745)
interrupt() vs isInterrupted() vs interrupted()
- public void interrupt()
- 設置線程狀態,如果線程處在WAITING/TIMED_WAITING狀態,則拋出InterruptedException,並清除中斷狀態;
- public boolean isInterrupted()
- 獲取線程中斷狀態;
- public static boolean interrupted()
- 獲取當前線程中斷狀態,然後清除中斷狀態,也就是說,如果連續執行兩次,第二次爲false