1 線程的建立html
方法1:實現Runnable接口(推薦)java
class Runner1 implements Runnable { public void run() { for(int i=0; i<30; i++) System.out.println("No. " + i); } } public class TestThread1 { public static void main(String args[]) { Thread t1 = new Thread(new Runner1()); t1.start(); } }
Runable是任務的概念,若是咱們直接這樣寫,會怎麼樣呢?只會在原來的線程(Main的)裏執行run方法。可見Runable更靈活,任務不用寫死在線程裏,能夠放到不一樣的線程,甚至線程池裏運行。把任務和運行分離。api
public class TestThread1 { public static void main(String args[]) { Runnable r1 = new Runner1(); r1.run(); } }
方法2:繼承Threadspa
class Thread1 extends Thread { public void run() { for(int i=0; i<100; i++) { System.out.println("Runner1 :" + i); } } } public class TestThread1 { public static void main(String args[]) { Thread1 t1 = new Thread1(); t1.start(); } }
2 線程的終止線程
參考:http://www.cnblogs.com/skywang12345/p/3479949.htmlcode
http://hapinwater.iteye.com/blog/310558htm
線程的終止主要有三種方式:blog
a. interrupt;繼承
b. 經過額外標識位;接口
c. suspend(暫停),resume(恢復),stop(終止),這三個方法已通過時。suspend和resume就像唱片機,能停能恢復,如今主要被wait/notify取代。stop終止線程太暴力,沒時間讓線程釋放資源,因此被淘汰了。
這些終止是讓別的線程終止本身,因別人啓動,因別人終止啊~。要終止本身只要從run方法return就行。
2.1 interrupt
每一個線程上都有一個標識位interrupted,說明該線程是否被中斷。當interrupt()時,只會改標誌位,不會真的終止線程。我這裏加了一個on標識來關掉這個線程,不然咱們就沒辦法關閉它了。
class ATask extends Thread { private volatile boolean on=true; public void run() { while (on) { System.out.println("I am running!"); for (int i = 0; i < 10000000; i++); } } public void shutdown(){ on=false; } } public class TestThread { public static void main(String[] args) throws Exception{ ATask t = new ATask(); t.start(); //運行一斷時間中斷線程 Thread.sleep(20); System.out.println("****************************"); System.out.println("Interrupted Thread!"); System.out.println("****************************"); t.interrupt(); Thread.sleep(20); System.out.println("ShutDown Thread!"); System.out.println("****************************"); t.shutdown(); } }
運行結果:
I am running! I am running! **************************** Interrupted Thread! **************************** I am running! I am running! ShutDown Thread! ****************************
interrupted能夠經過myThread.isInterrupted()查詢,也能夠經過Thread.interrupted()重置interrupted標誌位(設爲fasle)。
java給了線程編寫者自由,讓他定義在別人中斷本身時怎麼響應。主要分兩種狀況,一種是阻塞式的,另外一種是非阻塞式。
a. 阻塞式的:調用了sleep(), wait(), join()等方法就會進入阻塞狀態。就是說幹什麼已經不禁線程編寫者決定,控制權交到sleep裏。這些阻塞方法都會拋InterruptedException異常,我麼只要在catch裏響應Interrupt。能夠向下面乖乖地return,就終止了線程(並釋放相應資源);也能夠直接無論(catch裏什麼都不寫),這樣線程就會繼續while下去。這裏有個小細節,在拋InterruptedException時,虛擬機會重置interrupted標誌位。
class ATask extends Thread { public void run() { while(true){ try { System.out.println("I am running!"); sleep(1000); } catch (InterruptedException e) { System.out.println("ATask.run() interrupted!"); return; } } } } public class TestThread { public static void main(String[] args) throws Exception{ //將任務交給一個線程執行 Thread t = new ATask(); t.start(); //運行一斷時間中斷線程 Thread.sleep(20); System.out.println("****************************"); System.out.println("Interrupted Thread!"); System.out.println("****************************"); t.interrupt(); } }
運行結果:
I am running! **************************** Interrupted Thread! **************************** ATask.run() interrupted!
b. 非阻塞式方法:不是阻塞式的,控制權在本身手裏。
class ATask extends Thread { public void run() { //檢查程序是否發生中斷 while (!Thread.interrupted()) { System.out.println("I am running!"); for (int i = 0; i < 1000000; i++); } System.out.println("ATask.run() interrupted!"); } } public class TestThread{ public static void main(String[] args) throws Exception{ //將任務交給一個線程執行 Thread t = new ATask(); t.start(); //運行一斷時間中斷線程 Thread.sleep(20); System.out.println("****************************"); System.out.println("Interrupted Thread!"); System.out.println("****************************"); t.interrupt(); } }
運行結果:
I am running! I am running! **************************** Interrupted Thread! **************************** ATask.run() interrupted!
2.2 經過額外標識位
class ATask extends Thread { private volatile boolean on = true; public void run() { while(on){ System.out.println("I am running!"); for (int i = 0; i < 10000000; i++); } } public void shutDown() { on = false; } } public class TestThread { public static void main(String[] args) throws InterruptedException{ //將任務交給一個線程執行 ATask t = new ATask(); t.start(); //運行一斷時間中斷線程 Thread.sleep(20); System.out.println("****************************"); System.out.println("shutDown Thread!"); System.out.println("****************************"); t.shutDown(); } }
對比2.1,2.2兩種方法:
a 都能 自由地處理其餘線程的終止請求;
b 都能 在終止時釋放資源;
c 2.2不能終止處於阻塞狀態的線程。
3 線程的生命週期
線程的狀態起始很簡單,就是啓動->運行->終止。等待,超時等待,阻塞都是一種阻塞狀態,到用到時在分析,和線程的狀態沒太多關係,就那麼簡單。