一:stop終止線程
舉例子:
public class ThreadStop {
public static int i;
public static int j;
public static void main(String[] args) throws InterruptedException {
ThreadStop stop = new ThreadStop();
stop.test();
}
public void test() throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
i++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
}
});
thread.start();
Thread.sleep(1000);
//存在線程安全問題,破壞線程的原子性
thread.stop();
System.out.println("i= " + i + ", j= " + j);
}
}
上述例子中,最後輸出的i和j一個是1一個是0,按照正常情況,兩個值應該都是1纔對,所以可以看到,調用了stop之後,出現了這種問題,也就是說stop存在線程安全問題,會破壞線程的原子性。
二:Interrupt
Interrupt不會真的中止線程,只是給線程加上了一個標識,即isInterrupted從false變成了true;要是線程處於waiting、time waiting狀態,再調用Interrupt會清除線程的阻塞狀態,使線程狀態變爲runnable,而且isInterrupted也會從true變回false。下面舉例子說明:
public static void main(String[] args) throws InterruptedException {
ThreadInterrupt1 thread = new ThreadInterrupt1();
thread.test();
}
public void test() throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().isInterrupted());
System.out.println(Thread.currentThread().getState());
}
}
});
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
代碼運行結果如下:
可以看到線程剛開始運行的時候isInterrupted是false,運行一會之後,isInterrupted變成了true。
栗子2:
public void test2() throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
System.out.println("running......");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().isInterrupted());
System.out.println(Thread.currentThread().getState());
}
}
}
});
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
上面代碼,線程sleep後處於阻塞狀態,這個時候去執行Interrupt,會報java.lang.InterruptedException: sleep interrupted異常,而且線程的狀態也變成了runnable,isInterrupted也從true變回false,並且打印running語句會繼續執行,說明線程並沒有真的被中止。運行結果如下:
栗子3:
public void test3() throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//中止線程的正確方式,加個判斷
while (!Thread.currentThread().isInterrupted()) {
System.out.println("running......");
Thread.currentThread().interrupt();
}
}
});
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
上面的例子,能夠正確的把線程中止,輸出結果如下:
可以看到,輸出一次之後就中止了線程,線程沒有再掛起。
OK,到此結束。
—— 我自是年少,韶華傾負。