Java多線程(二)
1.多線程的阻塞狀態
join():一個線程調用了join()方法,必須等待另一個線程執行完畢後才能執行
package jsontest; public class RunableDemo implements Runnable { @Override public void run() { int i = 0 ; for(;i<10;i++){ System.out.println("-----------"+Thread.currentThread().getName()+"----"+i); } }public static void main(String[] args) { RunableDemo d = new RunableDemo() ; Thread t = new Thread(d) ; int k = 0 ; for(;k<10;k++){ System.out.println("---------"+Thread.currentThread().getName()+"----"+k); if(k==5){ t.start();try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } 結果: ---------main----0 ---------main----1 ---------main----2 ---------main----3 ---------main----4 ---------main----5 -----------Thread-0----0 -----------Thread-0----1 -----------Thread-0----2 -----------Thread-0----3 -----------Thread-0----4 -----------Thread-0----5 -----------Thread-0----6 -----------Thread-0----7 -----------Thread-0----8 -----------Thread-0----9 ---------main----6 ---------main----7 ---------main----8 ---------main----9
2.sleep():讓當前的線程暫停指定時間後執行,sleep(1):馬上執行
package jsontest; public class RunableDemo implements Runnable { @Override public void run() { int i = 0 ; for(;i<10;i++){ System.out.println("-----------"+Thread.currentThread().getName()+"----"+i); } } public static void main(String[] args) { RunableDemo d = new RunableDemo() ; Thread t = new Thread(d) ; int k = 0 ; for(;k<10;k++){ System.out.println("---------"+Thread.currentThread().getName()+"----"+k); if(k==5){ t.start(); try { Thread.sleep(5000);//thread線程執行完後,過5秒在執行main線程 } catch (InterruptedException e) { e.printStackTrace(); } } } } }
3.後臺線程(Daemon Thread)
目地:後臺線程主要是為其他線程(相對可以稱之為前臺線程)提供服務,或“守護線程”。如JVM中的垃圾回收線程。
生命周期:後臺線程的生命周期與前臺線程生命周期有一定關聯。主要體現在:當所有的前臺線程都進入死亡狀態時,後臺線程會自動死亡(其實這個也很好理解,因為後臺線程存在的目的在於為前臺線程服務的,既然所有的前臺線程都死亡了,那它自己還留著有什麽用...偉大啊 ! !)。
設置後臺線程:調用Thread對象的setDaemon(true)方法可以將指定的線程設置為後臺線程。
package jsontest; public class RunableDemo implements Runnable { @Override public void run() { int i = 0 ; for(;i<1000;i++){ System.out.println("-----------"+Thread.currentThread().getName()+"----"+i); } } public static void main(String[] args) { RunableDemo d = new RunableDemo() ; Thread t = new Thread(d) ; int k = 0 ; for(;k<10;k++){ System.out.println("---------"+Thread.currentThread().getName()+"----"+k); if(k==5){ t.setDaemon(true);//設置thread線程是後臺線程,當前臺main線程執行完畢後,後臺線程也就跟著結束了 t.start(); } } } }
判斷線程是否是後臺線程:調用thread對象的isDeamon()方法。
註:main線程默認是前臺線程,前臺線程創建中創建的子線程默認是前臺線程,後臺線程中創建的線程默認是後臺線程。調用setDeamon(true)方法將前臺線程設置為後臺線程時,需要在start()方法調用之前。前天線程都死亡後,JVM通知後臺線程死亡,但從接收指令到作出響應,需要一定的時間。
4.改變線程的優先級/setPriority():
每個線程在執行時都具有一定的優先級,優先級高的線程具有較多的執行機會。每個線程默認的優先級都與創建它的線程的優先級相同。main線程默認具有普通優先級。
設置線程優先級:setPriority(int priorityLevel)。參數priorityLevel範圍在1-10之間,常用的有如下三個靜態常量值:
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
獲取線程優先級:getPriority()。
註:具有較高線程優先級的線程對象僅表示此線程具有較多的執行機會,而非優先執行
package jsontest; public class RunableDemo implements Runnable { @Override public void run() { int i = 0 ; for(;i<100;i++){ System.out.println("-----------"+Thread.currentThread().getName()+"----"+i); } } public static void main(String[] args) { RunableDemo d = new RunableDemo() ; Thread t = new Thread(d) ; int k = 0 ; for(;k<100;k++){ System.out.println("---------"+Thread.currentThread().getName()+"----"+k); if(k==5){ t.setPriority(Thread.MAX_PRIORITY); t.start(); } } } }
5.線程讓步:yield()
yield()方法線程優先級有關,當某個線程調用yiled()方法從運行狀態轉換到就緒狀態後,CPU就緒狀態線程隊列中與該線程優先級相同或優先級更高的線程具有較多的執行機會
package jsontest; public class RunableDemo implements Runnable { @Override public void run() { int i = 0 ; for(;i<100;i++){ System.out.println("-----------線程1----"+i); } } public static void main(String[] args) { RunableDemo d = new RunableDemo() ; RunableDemo2 r = new RunableDemo2() ; Thread t = new Thread(d) ; Thread t2 = new Thread(r) ; t.setPriority(Thread.MAX_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY); int k = 0 ; for(;k<100;k++){ System.out.println("---------"+Thread.currentThread().getName()+"----"+k); if(k==20){ t.start(); t2.start(); Thread.yield(); } } } } class RunableDemo2 implements Runnable { @Override public void run() { int i = 0 ; for(;i<100;i++){ System.out.println("--------線程2----"+i); } } }
參考:http://www.cnblogs.com/lwbqqyumidi/p/3817517.html
Java多線程(二)