1. 程式人生 > >isAlive(),interrupted(),與isInterrupted()

isAlive(),interrupted(),與isInterrupted()

isAlive():

  • 作用:判斷當前執行緒是否是存活狀態,如果是返回true,否則返回false
  • 什麼是存活狀態?如果執行緒啟動後並未終止,就認為執行緒是存活的。(注意這個終止,後面會說到)
  • 如果執行緒已經start()後,當執行緒執行完時,呼叫isAlive()返回false,該執行緒已經被銷燬,不能再次start().
  • 程式碼演示:
public class Run_1 {
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread_1();
		t1.start();
		Thread.sleep(1000);//讓主執行緒多睡會兒,好讓Thread_1能執行完。
		System.out.println("我主執行緒都睡這麼久了,Thread_1執行緒應該執行完了吧,來看看他的狀態:"+t1.isAlive());
	}
}
class Thread_1 extends Thread{
	public void run(){
		System.out.println("執行緒Thread_1在執行。。。");
		System.out.println("Thread_1執行緒沒執行完,所以我是"+this.isAlive());
		System.out.println("Thread_1執行完畢");
	} 
}
執行緒Thread_1在執行。。。
Thread_1執行緒沒執行完,所以我是true
Thread_1執行完畢
我主執行緒都睡這麼久了,Thread_1執行緒應該執行完了吧,來看看他的狀態:false

interrupt()

  • 作用:呼叫該方法可使當前執行緒被打上一個停止標記,但是執行緒並沒有真正的停止,也就是說執行緒會繼續執行 (後面所說的打斷一律都是在說打上一個標記。)例如:
public class Run_1 {
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread_1();
		t1.start();
	}
}
class Thread_1 extends Thread{
	public void run(){
		System.out.println("執行緒Thread_1在執行。。。");
		this.interrupt();
		System.out.println("Thread_1執行完畢");
	} 
}
執行緒Thread_1在執行。。。
Thread_1執行完畢

靜態方法interrupted()

  • 作用:
    1. 檢視執行緒是否是停止狀態(是否有停止標記),如果有就返回true,否則返回false。
    2. 該方法在哪個執行緒中執行就檢測哪個執行緒的狀態,(注意:不是哪個執行緒物件呼叫該方法,而是在哪個執行緒中執行)。
    3. 呼叫一次該方法後,將標誌重置為false。
  • 程式碼演示0:
public class Run_1 {
	public static void main(String[] args) throws InterruptedException {
		Thread.currentThread().interrupt();
		System.out.println("主執行緒被標記上停止標誌,Thread.interrupted()又是在主執行緒中執行,所以打印出"+Thread.interrupted());
		System.out.println("標誌被清除,重置"+Thread.interrupted());
	}
}
主執行緒被標記上停止標誌,Thread.interrupted()又是在主執行緒中執行,所以打印出true
標誌被清除,重置false
  • 程式碼演示1:

public class Run_1 {
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread_1();
		t1.start();
		/*
		 *經過實踐,Thread_1中的程式碼5-6ms就完了
		 *,所以,主執行緒睡的時間不能超過5ms。因為超過
		 *5ms後,Thread_1執行緒執行完了,再在主執行緒中呼叫
		 *interrupt()方法是沒有意義的。
		 */
		Thread.sleep(2);
		/*
		 * 主執行緒睡2ms,cpu先分配給Thread_1執行緒,
		 * 2ms後再次分配給主執行緒時,Thread_1已經
		 * 執行了一段時間,但還沒執行完,在這個過程中
		 * 間使用interrupt()打斷才有說服力。
		 */
		t1.interrupt();
		System.out.println(t1.interrupted());
	}
}
class Thread_1 extends Thread{
	public void run(){
		long startTime = System.currentTimeMillis();
		for(int i = 0;i<900000000;i++){}
		long endTime = System.currentTimeMillis();
		System.out.println(endTime-startTime);
	} 
}
false
5

這個結果應該是在意料之中的吧,雖然打斷了,但是監測的並不是打斷的執行緒,而是主執行緒,因為該方法在主執行緒中執行。


isInterrupted()

  • 作用:也是檢測執行緒是否打斷,但是不同的是,哪個執行緒物件呼叫該方法就檢測哪個而且不重置標誌
  • 演示:還是用程式碼演示1的程式碼,但是使用的方法改變了

public class Run_1 {
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread_1();
		t1.start();
		/*
		 *經過計算,Thread_1中的程式碼5-6ms就完了
		 *,所以,主執行緒睡的時間不能超過5ms。因為超過
		 *5ms後,Thread_1執行緒執行完了,再在主執行緒中呼叫
		 *interrupt()方法是沒有意義的。
		 */
		Thread.sleep(2);
		/*
		 * 主執行緒睡2ms,cpu先分配給Thread_1執行緒,
		 * 2ms後再次分配給主執行緒時,Thread_1已經
		 * 執行了一段時間,但還沒執行完,在這個過程中
		 * 間使用interrupt()打斷才有說服力。
		 */
		t1.interrupt();
		System.out.println(t1.isInterrupted());
		
	}
}
class Thread_1 extends Thread{
	public void run(){
		long startTime = System.currentTimeMillis();
		for(int i = 0;i<900000000;i++){}
		long endTime = System.currentTimeMillis();
		System.out.println(endTime-startTime);
	} 
}
true
5

t1被打斷了,所以true,另外,想想程式碼的註釋。


如何停止執行緒

  • stop()方法
  • return語句
  • 拋異常,
run(){
......
if(this.interrupted()){throw new InterruptedException();}
.......
}

隨想:

isAlive()方法與interrupt()有沒有關係呢?


public class Run_5 {
	public static void main(String[] args) throws InterruptedException {
		Thread t = new Thread_5();
		System.out.println("是否活著3"+t.isAlive());
		t.start();
		Thread.currentThread().sleep(1000);
		System.out.println("是否活著4"+t.isAlive());
		System.out.println(t.isInterrupted());
	} 
}
class Thread_5 extends Thread{
	public void run(){
		System.out.println("THread_5執行緒正在執行");
		System.out.println("是否活著1"+this.isAlive());//執行緒是否在活著
		this.interrupt();//打斷該執行緒
		System.out.println(this.isInterrupted());//看看是否打斷
		System.out.println("是否活著2"+this.isAlive());//看看打斷後是否還活著	
	}
}
是否活著3false
THread_5執行緒正在執行
是否活著1true
true
是否活著2true
是否活著4false
false

瞎想來想去的結果:

  • 如果isAlive()返回false,interrupt()是沒有意義的,呼叫isInterrupted()方法的結果也只會有false。
  • 如果isAlive()返回true,interrupt()後還是true,不會造成影響。所以不要把isAlive中的終止和interrupt()搞混淆了。