根據Thread.State類中的描述,Java中線程有六種狀態:NEW,RUNNABLE,WAITING,TERMINATED,BLOCKED。ide
就緒狀態(NEW):當線程對象調用了start()方法以後,該線程就進入就緒狀態。就緒狀態的線程處於就緒隊列中,要等待JVM裏線程調度器的調度。this
運行狀態(RUNNABLE):若是就緒狀態的線程獲取 CPU 資源,就能夠執行 run(),此時線程便處於運行狀態。處於運行狀態的線程最爲複雜,它能夠變爲阻塞狀態、就緒狀態和死亡狀態。spa
阻塞狀態:若是一個線程執行了sleep(睡眠)、wait(等待)等方法,失去所佔用資源以後,該線程就從運行狀態進入阻塞狀態。在睡眠時間已到或得到設備資源後能夠從新進入就緒狀態。能夠分爲三種:操作系統
死亡狀態(TERMINATED):一個運行狀態的線程完成任務或者其餘終止條件發生時,該線程就切換到終止狀態。線程
值得注意的是,以上狀態爲JVM線程狀態,不反應操做系統線程狀態。code
線程狀態遷移圖orm
每個 Java 線程都有一個優先級,這樣有助於操做系統肯定線程的調度順序。線程優先級是一個正整數,全部建立的線程默認優先級爲5(Thread.NORM_PRIORITY),可設置最大優先級爲10(Thread.MAX_PRIORITY),最小優先級爲1(Thread.MIN_PRIORITY)。在全部獲得其餘資源並等待處理器資源的線程中,優先級高的線程理論上將被更有可能被優先調度。對象
守護線程意味着不重要的線程(騎士對於公主來講,是守護者,是無關緊要的備胎),於是當某進程只有守護線程在執行時,該進程會當即結束運行。 blog
1.新建類繼承Thread類。繼承
2.重寫run()方法。該run()方法的方法體就表明了線程須要完成的任務。
3.建立Thread子類的實例。
4.調用線程對象的start()方法來啓動該線程。
public class myThread { public static void main(String[] args){ Thread t = new newThread(); t.start(); } } class newThread extends Thread{ @Override public void run() { System.out.println(this.getName()+":start!"); } }
1.新建類實現Runnable接口。
2.重寫run方法。該run()方法的方法體就表明了線程須要完成的任務。
3.建立新建類的實例target。
4.以target做爲參數建立Thread的實例。
5.調用線程對象的start()方法來啓動該線程。
public class myThread { public static void main(String[] args){ newThread nt = new newThread(); Thread t = new Thread(nt); t.start(); } } class newThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+":start!"); } }
1.繼承Thread這種方法方便易用,更容易獲取當前線程對象。
2.實現Runnable接口這種方法能夠繼承其餘父類;多個線程能夠共享一個target對象,適合多個相同線程來處理同一份資源的狀況。
事實上,線程對象只有調用start()方法才能在新的線程中運行run()方法體中的代碼,而直接調用run()方法意味着在當前線程中調用run()方法,即run()方法被看成普通方法處理了,並不會建立新線程。
public class myThread { public static void main(String[] args){ newThread nt = new newThread(); Thread t = new Thread(nt,"myThread"); t.run(); } } class newThread implements Runnable{ @Override public void run() { System.out.println("Name:"+Thread.currentThread().getName()); } } //結果 Name:main
Thread() ,Thread(String name) //能夠傳入一個字符串或什麼也不傳入,就是建立一個什麼任務也不作的線程
Thread(Runnable target)
Thread(Runnable target,String name) //傳入一個可運行的對象,name做爲線程名稱
static Thread currentThread() //獲取當前線程對象
long getID() //獲取線程標識
String getName() //獲取線程名稱
int getPriority() //獲取線程優先級
Thread.state getState() //獲取線程狀態
public class myThread { public static void main(String[] args){ newThread nt = new newThread(); Thread t = new Thread(nt,"myThread"); t.start(); newThread.getInformation(Thread.currentThread()); newThread.getInformation(t); } } class newThread implements Runnable{ @Override public void run() { } static void getInformation(Thread t){ System.out.println("name:"+t.getName()); System.out.println("id:"+t.getId()); System.out.println("priority:"+t.getPriority()); System.out.println("state:"+t.getState()); } } //結果 name:main id:1 priority:5 state:RUNNABLE name:myThread id:13 priority:5 state:TERMINATED
void setName() //設置線程名稱
void setPriority() //設置線程優先級
void setDaemon(Boolean on) //設置爲守護線程,只有當線程調用start()方法以前纔可調用
boolean isAlive() //判斷線程是否死亡,
boolean isDaemon() //判斷線程是否爲守護線程
boolean isInterrupted() //判斷線程是否中斷,而且將其變爲非中斷狀態
public class myThread { public static void main(String[] args){ newThread nt = new newThread(); Thread t = new Thread(nt,"myThread"); System.out.println("未調用start()時:"+t.isAlive()); t.setDaemon(true); t.start(); newThread.getInformation(t); newThread.getInformation(Thread.currentThread()); } } class newThread implements Runnable{ @Override public void run() { } static void getInformation(Thread t){ System.out.println(t.getName()+"-isAlive:"+t.isAlive()); System.out.println(t.getName()+"-isDaemon:"+t.isDaemon()); System.out.println(t.getName()+"-isInterrupted:"+t.isInterrupted()); } } //結果 未調用start()時:false myThread-isAlive:true myThread-isDaemon:true myThread-isInterrupted:false main-isAlive:true main-isDaemon:false main-isInterrupted:false
該方法讓當前線程暫停執行一段時間。
static void sleep(long millis) //暫停millis毫秒
static void sleep(long millis,long nanos) //暫停millis毫秒+nanos納秒
join意味加入,能夠抽象地認爲它是加入當前線程隊伍,也就是說,發生t.join()調用時調用方t加入當前線程隊伍,當前線程須要等待t線程執行完畢後纔開始執行。
public class myThread { public static void main(String[] args)throws InterruptedException { newThread nt = new newThread(); Thread t = new Thread(nt,"subThread"); t.start(); t.join(); for (int i = 1; i <= 1000; i++) { if (i%500==0) { System.out.println("mainThread finish!"); } } } } class newThread implements Runnable{ @Override public void run(){ for (int i = 1; i <= 1000; i++) { try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } if (i%500==0) System.out.println("subThread finish!"); } } }
結果以下,主線程顯然是比子線程執行時間更短,然而仍是主線程最後執行完
subThread finish! subThread finish! mainThread finish! mainThread finish!
方法還有另外兩個重載形式
void join(long millis) //等待millis毫秒
void join(long millis,long nanos) //等待millis毫秒+nanos納秒
join()內部使用wait()方法和notifyall()方法來實現的,於是它與sleep()方法的區別是,sleep方法不會釋放持有的鎖,而join()方法會釋放持有的鎖。
//將t.join()改成t.join(50,50)後,結果不一樣: mainThread finish! mainThread finish! subThread finish! subThread finish!
讓出當前線程cup的使用權,此時就緒隊列中高優先級 的線程將被執行,此外該方法不釋放線程持有的鎖。