What is Java thread priority? 什麼是java執行緒優先順序
就一個小程式,執行一次輸出結果不一樣,這是因為執行緒排程方法不能確定,取決你當前作業系統的程序,執行緒排程優先順序。
所以要想執行緒按一定的順序執行,哪麼只能選擇Synchronized 互斥(物件鎖)和 wait notify合作關係了。
一、概念
1、幹活執行緒建立時是以排隊的順序,排在前面的幹活執行緒先執行,
同時也給了一個預設的優先順序 5。
2、sleep(100) :可以暫停當前幹活執行緒的執行,從就緒佇列另取一個幹活執行緒去cpu執行。
是不是一定按照排隊的順序取一個幹活執行緒呢!不一定,還取決你使用的作業系統。
3、Thread.yield():只是給執行緒排程者出主意的人,你可以叫別的幹活執行緒幹活了,這是最佳轉換時間。
排程程式:有決定權,叫不叫別的幹活執行緒幹活不一定。
Thread.yield():唯一 的好處是 確保a context switch 發生。
Context Switch:作業系統切換任務,先前一個任務的Context都被保持下來,新任務的Context會被裝載進來
4、排程程式改預設優先順序5,把特急的設定成高優先順序10,目前就三種優先順序,如果改的話,只能改成最低,最高。
按道理高優先順序的執行緒會先執行,但是還是不一定,有時低優先順序也開始執行。
public final static int MIN_PRIORITY = 1; //最低優先順序
public final static int NORM_PRIORITY = 5;//幹活執行緒建立預設優先順序
public final static int MAX_PRIORITY = 10;//hhhh
所以對於設定優先順序,只是本地記號,一切由作業系統決定。
二、影響執行緒優先順序是否有效的幾個因素:
http://www.javamex.com/tutorials/threads/priority.shtml
CPU distribution:像我們平時有一個大蛋糕,排程者每個人分一塊,這就是分配。
Priority優先順序:執行順序從高到低
setPriority(),我們想當然,優先順序高的執行緒先執行,低的後執行,但是有可能和我想法不一樣,理由:
1、由於我們的 OS and VM 版本不同, Thread.setPriority() 也許什麼也不做;
2、在UNIX 系統中,表示分配。
3、執行緒優先順序是由 "global" and "local" priority settings 構成。
Java's setPriority() 方法工作在 local priority 。
理由:你當前軟體設定的優先順序不能直接影響系統的其它軟體吧!
你通常不想,滑鼠點選執行緒或處理音訊資料被隨機使用者執行緒取代吧!
當我們正在看一個好看的電影時,隨便一個小軟體執行,這時電影停下,讓小軟體執行,哈哈,我們會被氣死。
4、java 有1--10個優先順序,不同的作業系統也許有,也許沒有,看作業系統說明書。
5、當一些低優先順序的執行緒長時間得不到執行,作業系統給一個臨時優先順序boost(加速),低優先順序執行緒佔用cpu.
6、大多數作業系統的執行緒排程者有時對執行緒優先順序執行臨時的操作。
例如:當一個執行緒接收一個事件或它正在等待一個i/o,不用時可以在任務管理自己手動調整優先順序最低。
7、
1》你的應用通常不知道其他程序正在執行的是什麼執行緒,因此改變一個執行緒的優先順序對整個系統的影響也許不可預測。
2》例如,你也許發現,你設計在“後臺執行的低優先順序執行緒”幾乎根本不執行,這是因為防毒軟體執行緒的優先順序稍微高些(但仍然低於正
常),並且防毒軟體不同,佔用記憶體和消耗cpu這些效能也不同。
8、我們自己可以在“工作管理員”任意調整每一程序的優先順序,如果不太重要的程序設定成“低”,哪麼其它的程式速度會大幅提高。
一個程序的優先順序發生變化,裡面所有的執行緒的優先順序發生了變化。
所以,上面的影響總是存在,但是自己小軟體設定優先順序也是必要的。
比如:學校的班級排名和全年級排名。
三、轉載 http://www.javamex.com/tutorials/threads/priority_what.shtml
What is Java thread priority?
In our introduction to thread priority, we pointed out some problems with the system, notably differences between what priority actually means on different systems. Here, we'll look at how thread priority is actually implemented in Windows and Linux.
1、Windows priorities 和 java優先順序對應表。
In the Hotspot VM for Windows, setPriority() map to Windows relative priorities (set by the SetThreadPriority() API call). The actual mappings were changed between Java 5 and Java 6 as follows:
Java Priority | Windows Priority (Java 5) | Windows Priority (Java 6) |
---|---|---|
1 | THREAD_PRIORITY_LOWEST | |
2 | ||
3 | THREAD_PRIORITY_BELOW_NORMAL | |
4 | ||
5 | THREAD_PRIORITY_NORMAL | THREAD_PRIORITY_NORMAL |
6 | THREAD_PRIORITY_ABOVE_NORMAL | |
7 | THREAD_PRIORITY_ABOVE_NORMAL | |
8 | THREAD_PRIORITY_HIGHEST | |
9 | THREAD_PRIORITY_HIGHEST | |
10 | THREAD_PRIORITY_TIME_CRITICAL |
THREAD_PRIORITY_TIME_CRITICAL:最高優先順序了。
In effect, the priority mappings were 'shifted down' to avoid THREAD_PRIORITY_TIME_CRITICAL, apparently following reports that this setting could affect vital processes such as audio. Note that there is really no such mapping to THREAD_PRIORITY_IDLE as suggested by Oaks & Wong (they were possibly misinterpreting a dummy value that appears at the beginning of the priority mapping table in the VM source code).
On Windows, thread priority is a key element in deciding which thread gets scheduled, although the overall priority of a thread is a combination of the process's priority class, the thread's relative priority (values from the table above), plus any temporary "boost" given in specific circumstances (such as on returning from a wait on I/O). But in general:
在Windows,執行緒優先順序是決定哪一個執行緒排程的關鍵部分,程序的優先順序類構成全部執行緒的優先順序,
Windows執行緒的優先順序:上面表給出的執行緒+臨時加速的執行緒
boost:加速
低優先順序執行緒必須在所有高優先順序執行緒處於waiting狀態,才有機會佔有cpu。
Lower-priority threads are given CPU when all higher priority threads are waiting (or otherwise unable to run) at that given moment.The actual proprtion of CPU allotted to a thread therefore depends on how often that situation occurs— there's no relation per se(本身) between priority and CPU allocation.
實際上分配一個執行緒佔有cpu的比例,取決於這種情況的多久發生一次,執行緒的優先順序和cpu的分配本身無聯絡,對,unix 就是這樣
例如:下圖10個執行緒同時執行,60s內,10個執行緒各佔有cpu多少時間,佔的時間/60s=一個執行緒佔有的比例,
而9,10執行緒明顯佔有很大的比例,明顯還是和執行緒的優先順序有關,是的,因為下面是window 系統。
Now of course, if this was literally the be-all and end-all to thread scheduling, then there'd quite possibly be lower-priority threads that barely got any CPU at all, being continually starved by higher-priority threads that needed CPU.
非常有可能低優先順序執行緒根本得不到cpu執行,當高優先順序執行緒繼續佔用cpu時,會餓死低優先順序執行緒。
So Windows has a fallback mechanism, whereby a thread that hasn't run for a long time is given a temporary priority boost.
這種情況的解決辦法:就是長時間沒有執行的執行緒給一個臨時優先順序boost(加速),佔用cpu.
(For more details about some of the points mentioned here, see the section on thread scheduling.)
What this generally means is that on Windows:當所有執行緒競爭cpu時,執行緒的優先順序並沒有什麼意義。
Thread priority isn't very meaningful when all threads are competing for CPU.As an illustration, Figure 1 opposite shows the results of an experiment in which ten threads are run concurrently, one thread with each Java priority.
圖1例子:橫座標(執行緒優先順序1--10),縱座標就是產生的數字。
規定:10個執行緒同時執行,60s後全部結束,檢視每一執行緒產生了多少個數字,這些數字被看作這個執行緒佔用cpu的時間。
測試結果 :執行緒優先順序1-8 差不多佔用cpu的時間是一樣的。9,10 分配執行緒佔用大部分cpu時間。
主要原因就是THREAD_PRIORITY_HIGHEST 有最高優先順序。
測試環境: Java 6 Update 10. Vista 雙核,重複實驗多次,圖形是一樣的。
linux 圖形不一樣。
Each thread sits in a CPU-intensive(cpu一直處於計算中) loop (continually a
random number using a XOR Shift異或移位 generator). Each thread keeps a count of how many numbers it has generated1. After a certain period (60 seconds in this case), all threads are told to stop and queried to find out how many numbers they generated; the number generated is taken as an indication of the CPU time allocated to that thread2. As can be seen, thread priorities 1-8 end up with a practically equal share of the CPU, whilst priorities 9 and 10 get a vastly greater share (though with essentially no difference between 9 and 10). The version tested was Java 6 Update 10. For what it's worth, I repeated the experiment on a dual core machine running Vista, and the shape of the resulting graph is the same. My best guess for the special behaviour of priorities 9 and 10 is that THREAD_PRIORITY_HIGHEST in a foreground window has just enough priority for certain other special treatment by the scheduler to kick in (for example, threads of internal priority 14 and above have their full quantum
replenished after a wait, whereas lower priorities have them reduced by 1).
Java thread priority | Linux nice value |
---|---|
1 | 4 |
2 | 3 |
3 | 2 |
4 | 1 |
5 | 0 |
6 | -1 |
7 | -2 |
8 | -3 |
9 | -4 |
10 | -5 |
2、Linux priorities
Under Linux, you have to go through more hoops to get thread priorities to function at all, although in the end, they may be more useful than under Windows. In Linux:
- thread priorities only work as of Java 6 onwards;
- for them to work, you must be running as root (or with root privileges via setuid);
- the JVM parameter -XX:UseThreadPriorities must be included.
The rationale behind requiring root privileges to alter thread priorities largely eludes me. Whether or not Linux itself generally should place such a restriction on changing nice values is arguable, bit since it doesn't, it seems odd to add it to the JVM (as opposed to, say, building in a restriction via the Java SecurityManager). And does anyone really run, say, their web server as root?
Assuming you go through these steps to enable them, Java thread priorities in Hotspot map to nice values. Unlike Windows priorities, Linux nice values are used as a target for CPU allocation (although like Windows, recent versions of Linux— from kernel 2.6.8 onwards— also apply various heuristics to temporarily boost or penalise threads). The mappings from Java priorities to Linux nice values are given in the table opposite. Note that:
- nice value means "how nice the thread is to other threads", so a lower number means higher priority;
- Java doesn't actually map to the full range (nice values go from -20 to 19), probably to prevent negative impact on system threads.
Figure 2 shows the results of the thread priority experiment repeated under Linux with kernel 2.6.18. The different coloured traces simply represent 3 separate runs of the experiment. The graph shows that there is a correlation between Java priority (nice value) and CPU allocation, although it is far from linear.
四、程式碼,每次執行結果不一樣。
package concurrency; import java.util.concurrent.*; public class SimplePriorities implements Runnable { private int countDown = 5; private volatile double d; // No optimization private int priority; public SimplePriorities(int priority) { this.priority = priority; } public String toString() { return Thread.currentThread() + ": " + countDown; } public void run() { Thread.currentThread().setPriority(priority); while (true) {//當語句執行完,那麼讓另一個任務執行。 // An expensive, interruptable operation: for (int i = 1; i < 100000; i++) { d += (Math.PI + Math.E) / (double) i; if (i % 1000 == 0) Thread.yield(); } System.out.println(this); if (--countDown == 0) return; } } public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) exec.execute(new SimplePriorities(Thread.MIN_PRIORITY)); exec.execute(new SimplePriorities(Thread.MAX_PRIORITY)); exec.shutdown(); } } |