java 线程 通过interrupted_Java线程的传说(1)——中断线程Interrupted的用处
中斷線程 —— interrupt()
一個正在運行的線程除了正常的時間片中斷之外,能否被其他線程控制?或者說其他線程能否讓指定線程放棄CPU或者提前結(jié)束運行? 除了線程同步機制之外,還有兩種方法: (1) Thread.stop(), Thread.suspend(), Thread.resume() 和Runtime.runFinalizersOnExit() 這些終止線程運行的方法 。這些方法已經(jīng)被廢棄,使用它們是極端不安全的。 (2) Thread.interrupt() 方法是很好的選擇。但是使用的時候我們必須好好理解一下它的用處。
//無法中斷正在運行的線程代碼
class TestRunnable implements Runnable{
public void run(){
while(true)
{
System.out.println( "Thread is running..." );
long time = System.currentTimeMillis();//去系統(tǒng)時間的毫秒數(shù)
while((System.currentTimeMillis()-time < 1000)) {
//程序循環(huán)1秒鐘,不同于sleep(1000)會阻塞進程。
}
}
}
}
public class ThreadDemo{
public static void main(String[] args){
Runnable r=new TestRunnable();
Thread th1=new Thread(r);
th1.start();
th1.interrupt();
}
}
//運行結(jié)果:一秒鐘打印一次Thread is running...。程序沒有終止的任何跡象
上面的代碼說明interrupt()并沒有中斷一個正在運行的線程,或者說讓一個running中的線程放棄CPU。那么interrupt到底中斷什么。 首先我們看看interrupt究竟在干什么。 當(dāng)我們調(diào)用th1.interrput()的時候,線程th1的中斷狀態(tài)(interrupted status) 會被置位。我們可以通過Thread.currentThread().isInterrupted() 來檢查這個布爾型的中斷狀態(tài)。 在Core Java中有這樣一句話:"沒有任何語言方面的需求要求一個被中斷的程序應(yīng)該終止。中斷一個線程只是為了引起該線程的注意,被中斷線程可以決定如何應(yīng)對中斷"。好好體會這句話的含義,看看下面的代碼:
//Interrupted的經(jīng)典使用代碼
public void run(){
try{
....
while(!Thread.currentThread().isInterrupted()&& more work to do){
// do more work;
}
}catch(InterruptedException e){
// thread was interrupted during sleep or wait
}
finally{
// cleanup, if required
}
}
很顯然,在上面代碼中,while循環(huán)有一個決定因素就是需要不停的檢查自己的中斷狀態(tài)。當(dāng)外部線程調(diào)用該線程的interrupt 時,使得中斷狀態(tài)置位。這是該線程將終止循環(huán),不在執(zhí)行循環(huán)中的do more work了。
這說明: interrupt中斷的是線程的某一部分業(yè)務(wù)邏輯,前提是線程需要檢查自己的中斷狀態(tài)(isInterrupted())。
但是當(dāng)th1被阻塞的時候,比如被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞時。調(diào)用它的interrput()方法。可想而知,沒有占用CPU運行的線程是不可能給自己的中斷狀態(tài)置位的。這就會產(chǎn)生一個InterruptedException異常。
//中斷一個被阻塞的線程代碼
class TestRunnable implements Runnable{
public void run(){
try{
Thread.sleep(1000000); //這個線程將被阻塞1000秒
}catch(InterruptedException e){
e.printStackTrace();
//do more work and return.
}
}
}
public class TestDemo2{
public static void main(String[] args) {
Runnable tr=new TestRunnable();
Thread th1=new Thread(tr);
th1.start(); //開始執(zhí)行分線程
while(true){
th1.interrupt(); //中斷這個分線程
}
}
}
/*運行結(jié)果:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at TestRunnable.run(TestDemo2.java:4)
at java.lang.Thread.run(Unknown Source)*/
* 如果線程被阻塞,它便不能核查共享變量,也就不能停止。這在許多情況下會發(fā)生,例如調(diào)用 * Object.wait()、ServerSocket.accept()和DatagramSocket.receive()時,他們都可能永 * 久的阻塞線程。即使發(fā)生超時,在超時期滿之前持續(xù)等待也是不可行和不適當(dāng)?shù)?#xff0c;所以,要使 * 用某種機制使得線程更早地退出被阻塞的狀態(tài)。很不幸運,不存在這樣一種機制對所有的情況 * 都適用,但是,根據(jù)情況不同卻可以使用特定的技術(shù)。使用Thread.interrupt()中斷線程正 * 如Example1中所描述的,Thread.interrupt()方法不會中斷一個正在運行的線程。這一方法 * 實際上完成的是,在線程受到阻塞時拋出一個中斷信號,這樣線程就得以退出阻塞的狀態(tài)。更 * 確切的說,如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,那么, * 它將接收到一個中斷異常(InterruptedException),從而提早地終結(jié)被阻塞狀態(tài)。
總結(jié)
以上是生活随笔為你收集整理的java 线程 通过interrupted_Java线程的传说(1)——中断线程Interrupted的用处的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中json重复数据结构_JS实现
- 下一篇: python querystring e