search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

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

所以對於設置優先順序,只是本地記號,一切由操作系統決定。

二、影響線程優先順序是否有效的幾個因素:

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、我們自己可以在「任務管理器」任意調整每一進程的優先順序,如果不太重要的進程設置成「低」,哪么其它的程序速度會大幅提高。

一個進程的優先順序發生變化,裡面所有的線程的優先順序發生了變化。

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 to Windows priority mappings

Java PriorityWindows Priority (Java 5)Windows Priority (Java 6)
1THREAD_PRIORITY_LOWEST
2
4

5THREAD_PRIORITY_NORMAL 6THREAD_PRIORITY_ABOVE_NORMAL 7 8THREAD_PRIORITY_HIGHEST 9 10THREAD_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。

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時,線程的優先順序並沒有什麼意義。

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 generated12. 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 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 to nice value mappings in Linux

Java thread priorityLinux 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;

}

}



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦