Java 並發 線程的優先級


Java 並發 線程的優先級

@author ixenos

 

 

 

 低優先級線程的執行時刻


 

1.在任意時刻,當有多個線程處於可運行狀態時,運行系統總是挑選一個優先級最高的線程執行,只有當線程停止、退出或者由於某些原因不執行的時候,低優先級的線程才可能被執行

2.兩個優先級相同的線程同時等待執行時,那么運行系統會以round-robin的方式選擇一個線程執行(即輪詢調度,以該算法所定的)(Java的優先級策略是搶占式調度!)

3.被選中的線程可因為一下原因退出,而給其他線程執行的機會:

  1) 一個更高優先級的線程處於可運行狀態(Runnable)

  2)線程主動退出(yield),或它的run方法結束

  3)在支持分時方式的系統上,分配給該線程的時間片結束

4.Java運行系統的線程調度算法是搶占式(preemptive)的,當更高優先級的線程出現並處於Runnable狀態時,運行系統將選擇高優先級的線程執行

5.例外地,當高優先級的線程處於阻塞狀態且CPU處於空閑時,低優先級的線程也會被調度執行

 1 public class PriorityExample{
 2     public static void main(Strinig[] args){
 3         Thread a = new PThread("A");
 4         Thread b = new PThread("B");
 5         a.setPriority(7); //設置優先級
 6         a.setPriority(1);
 7     }
 8 }
 9 
10 class PThread extends Thread{
11     public PThread(String n){
12         super(n);
13     }
14 
15     public void run(){
16         for(int i=0; i<5000000; i++){
17             if(i%5000000 == 0){
18                 System.out.print(getName());
19             }
20         }
21     }
22 }

 

輸出 AAAAAAAAABBBBBBBBB

 

 

利己線程


 

1.一般地,在線程中可以調用sleep方法,放棄當前線程對處理器的使用,從而使各個線程均有機會得到執行,但有時候線程可能不遵循這個規則!

1 public void run(){
2     for(int i=0; i<5000000; i++){
3         if(i%5000000 == 0){
4             System.out.print(getName());
5         }
6     }
7 }

 

2.for循環是一個緊密循環,一旦運行系統選擇了有for循環體的線程執行,該線程就不會放棄對處理器的使用權,除非for循環自然終止或者該線程被一個有更高優先級的線程搶占,這樣的線程稱為利己線程

3.利己線程一般不引起問題,但有時會讓其他的線程得到處理器使用權之前等待一段很長的時間

 

 

分時方式


 

1.為解決利己線程可能長時間占據CPU的問題,有些系統通過分時方式來限制利己線程的執行,如Windows2000或WindowsNT系統

2.在分時方式中,處理器的分配按照時間片來划分,對於那些具有相同最高優先級的多個線程,分時技術會交替地分配CPU時間片給他們執行,當時間片結束,即使該線程沒有運行結束,也會讓出CPU使用權

3.注釋掉優先級設置后,輸出變成了AAAAABBBBBAAABBB或者AABBAAAABBBBAABBA

 1 public class PriorityExample{
 2     public static void main(Strinig[] args){
 3         Thread a = new PThread("A");
 4         Thread b = new PThread("B");
 5         //a.setPriority(7); //設置優先級
 6         //a.setPriority(1);
 7     }
 8 }
 9 
10 class PThread extends Thread{
11     public PThread(String n){
12         super(n);
13     }
14 
15     public void run(){
16         for(int i=0; i<5000000; i++){
17             if(i%5000000 == 0){
18                 System.out.print(getName());
19             }
20         }
21     }
22 } 

 

而如果在另一個不支持分時技術的平台上運行程序,得到的輸出結果可能是確定的! AAAAAAAAABBBBBBBBB

 

4.Java運行系統不實現分時,分時是和平台相關的,而有的平台不支持分時,在編寫Java多線程程序的時候,不能過分依賴分時技術來保證各個線程都有公平的執行機會!通常應編寫那種可以主動放棄處理器使用權的程序,同時一個線程也可以調用yield方法主動放棄對處理器的使用權

  注意:使用yield只能給同優先級的線程提供執行機會,如果沒有同優先級的線程處於可運行狀態,yield方法將被忽略!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM