一、線程的狀態 線程一般具有五種狀態,即創建、就緒、運行、阻塞、終止。 它們之間的關係: 二、線程操作相關方法 1.設置和取得線程名稱。 如果不設置線程名稱,系統會自動分配線程名,一般格式為Thread-Xx 獲取當前線程用Thread.currentThread.getName(); 線程名稱的設 ...
一、線程的狀態
線程一般具有五種狀態,即創建、就緒、運行、阻塞、終止。
它們之間的關係:
二、線程操作相關方法
1.設置和取得線程名稱。
如果不設置線程名稱,系統會自動分配線程名,一般格式為Thread-Xx
獲取當前線程用Thread.currentThread.getName();
線程名稱的設置,Thread類中已經建好了各種構造器。
中間帶有String的基本都是設置線程名稱的,大家可以自行看下。
1 public class TestThread { 2 public static void main(String[] args) { 3 TestSleep s = new TestSleep(); 4 Thread t1 = new Thread(s, "線程t1"); 5 Thread t2 = new Thread(s, "線程t2"); 6 Thread t3 = new Thread(s); 7 8 t1.start(); 9 t2.start(); 10 t3.start(); 11 } 12 } 13 14 class TestSleep implements Runnable{ 15 public void run(){ 16 for(int i = 0; i < 5; i++){ 17 System.out.println(Thread.currentThread().getName() + " i:" + i ); 18 } 19 } 20 }
運行結果: 線程t1 i:0 Thread-0 i:0 線程t2 i:0 Thread-0 i:1 線程t1 i:1 Thread-0 i:2 線程t2 i:1 Thread-0 i:3 線程t1 i:2 Thread-0 i:4 線程t2 i:2 線程t1 i:3 線程t1 i:4 線程t2 i:3 線程t2 i:4
2.判斷線程是否啟動
判斷當前線程是否“”活著“”,可能大家對於線程活著這個定義不是很清楚。說明點就是線程啟動了,而且也沒有死亡就稱之為活著。
1 public class TestThread { 2 public static void main(String[] args) { 3 TestSleep s = new TestSleep(); 4 Thread t1 = new Thread(s, "線程t1"); 5 Thread t2 = new Thread(s, "線程t2"); 6 System.out.println(t1.isAlive()); //false 7 System.out.println(t2.isAlive()); //false 8 t1.start(); 9 System.out.println(t1.isAlive()); //ture 10 System.out.println(t2.isAlive()); //flase 11 t2.start(); //著這裡加個延遲幾秒就會發現下麵會列印false。 12 System.out.println(t1.isAlive()); //這裡的狀態是不定的,假如指向到這t1和t2沒有執行完,那麼就是true 13 System.out.println(t2.isAlive()); //如果已經執行完畢進入死亡狀態,這裡就是false 14 } 15 } 16 17 class TestSleep implements Runnable{ 18 public void run(){ 19 for(int i = 0; i < 5; i++){ 20 System.out.println(Thread.currentThread().getName() + " i:" + i ); 21 } 22 } 23 }
false false true false true true 線程t1 i:0 線程t1 i:1 線程t1 i:2 線程t1 i:3 線程t1 i:4 線程t2 i:0 線程t2 i:1 線程t2 i:2 線程t2 i:3 線程t2 i:4
當現場處於就緒狀態和運行狀態都是true,可能又會有疑問那處於堵塞狀態了。
我們接下里就測試下處於堵塞狀態下isAlive();
public class TestThread { public static void main(String[] args) { TestSleep s = new TestSleep(); Thread t1 = new Thread(s, "線程t1"); Thread t2 = new Thread(s, "線程t2"); System.out.println(t1.isAlive()); System.out.println(t2.isAlive()); t1.start(); System.out.println(t1.isAlive()); System.out.println(t2.isAlive()); t2.start(); System.out.println(t1.isAlive()); System.out.println(t2.isAlive()); } } class TestSleep implements Runnable{ synchronized public void run(){ try { this.wait(); //當前線程等待,即進堵塞狀態 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i = 0; i < 5; i++){ System.out.println(Thread.currentThread().getName() + " i:" + i ); } } }
運行結果: false false true false true true
可以發現最後兩個線程都堵塞了,但最後列印的狀態還是true,處於堵塞狀態的線程也是存活的。
3.線程的強制加入
1 public class TestThread { 2 public static void main(String[] args) { 3 TestSleep s = new TestSleep(); 4 Thread t1 = new Thread(s, "線程t1"); 5 t1.start(); 6 for(int i = 0; i < 10; i++){ 7 if(i == 5){ 8 try { 9 t1.join(); //當i為5時,強制加入線程t1 10 } catch (InterruptedException e) { 11 // TODO Auto-generated catch block 12 e.printStackTrace(); 13 } 14 } 15 System.out.println(Thread.currentThread().getName() + i); 16 } 17 } 18 } 19 20 class TestSleep implements Runnable{ 21 synchronized public void run(){ 22 for(int i = 0; i < 5; i++){ 23 System.out.println(Thread.currentThread().getName() + " i:" + i ); 24 } 25 } 26 }
main0 main1 main2 main3 main4 線程t1 i:0 線程t1 i:1 線程t1 i:2 線程t1 i:3 線程t1 i:4 main5 main6 main7 main8 main9
強制加入的線程運行完畢後才會讓出資源。
4.線程的休眠
1 public class TestThread { 2 public static void main(String[] args) { 3 TestSleep s = new TestSleep(); 4 Thread t1 = new Thread(s, "線程t1"); 5 t1.start(); 6 } 7 } 8 9 class TestSleep implements Runnable{ 10 synchronized public void run(){ 11 for(int i = 0; i < 5; i++){ 12 try { 13 Thread.sleep(1000); 14 } catch (InterruptedException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 System.out.println(Thread.currentThread().getName() + " i:" + i ); 19 } 20 } 21 }
sleep(填入的數字代表毫秒),上圖中填入的是1000代表休眠1s,運行後我們會發現每隔一秒列印一次線程名+ i的值。
5.線程的中斷。
可以使用interrupt()方法中斷線程的運行。
1 public class TestThread { 2 public static void main(String[] args) { 3 TestSleep s = new TestSleep(); 4 Thread t1 = new Thread(s, "線程t1"); 5 t1.start(); 6 t1.interrupt(); 7 } 8 } 9 10 class TestSleep implements Runnable{ 11 public void run(){ 12 System.out.println("開始休眠10s"); 13 try { 14 Thread.sleep(10000); 15 System.out.println("完成休眠"); 16 } catch (InterruptedException e) { 17 // TODO Auto-generated catch block 18 System.out.println("當前線程被中斷,休眠失敗"); 19 }
20 System.out.println("run正常運行結束"); 21 } 22 }
如上代碼沒有被中斷應是線程進入run中“開始休眠10s”,10s後會列印出“休眠完成”,"正常運行結束。"
運行我們會發現一運行就出現了“開始休眠10s”,"當前線程被中斷,休眠失敗",說明執行t1.interrupt()後t1線程被中斷了執行。
運行結果:
開始休眠10s
當前線程被中斷,休眠失敗
6.線程的禮讓
1 public class TestThread { 2 public static void main(String[] args) { 3 TestSleep s = new TestSleep(); 4 Thread t1 = new Thread(s, "線程t1"); 5 t1.start(); 6 for(int i = 0; i < 10; i++){ 7 if(i == 5){ 8 System.out.println("開始禮讓:"); 9 Thread.currentThread().yield(); 10 } 11 System.out.println(Thread.currentThread().getName() + i); 12 } 13 } 14 } 15 16 class TestSleep implements Runnable{ 17 public void run(){ 18 for(int i = 0; i < 5; i++){ 19 System.out.println(Thread.currentThread().getName() + " i:" + i ); 20 } 21 } 22 }
用yield()可以讓當前線程暫停,暫時讓其他線程來運行。
是暫時讓一會不是一直讓,只讓一會就不讓了,具體調度要看CPU。
運行結果: main0 main1 main2 main3 main4 開始禮讓: 線程t1 i:0 main5 main6 main7 main8 線程t1 i:1 main9 線程t1 i:2 線程t1 i:3 線程t1 i:4