[英]Thread execution ordering by setting priority
我按以下順序設置了線程的優先級
然后是B然后C。但是當我在程序運行時,有時B在A之前運行。我不理解這個執行,因為我將B的優先級設置為低於A的優先級。
public class AThread implements Runnable{
public void run(){
System.out.println("In thread A");
}}
public class BThread implements Runnable {
public void run(){
System.out.println("In thread B");
}
}
public class CThread implements Runnable {
public void run(){
System.out.println("In thread C");
}
}
public class ThreadPriorityDemo {
public static void main(String args[]){
AThread A = new AThread();
Thread tA = new Thread(A);
BThread B = new BThread();
Thread tB = new Thread(B);
CThread C = new CThread();
Thread tC = new Thread(C);
tA.setPriority(Thread.MAX_PRIORITY);
tC.setPriority(Thread.MIN_PRIORITY);
tB.setPriority(tA.getPriority() -1);
System.out.println("A started");
tA.start();
System.out.println("B started");
tB.start();
System.out.println("C started");
tC.start();
}
}
線程優先級可能不是您認為的那樣。
線程的優先級是建議操作系統在涉及這兩個線程的任何調度或CPU分配決策點中優先選擇一個線程而不是另一個線程。 但是如何實現它取決於操作系統和JVM實現。
JavaMex對線程優先級有很好的討論。 要點是:
請務必閱讀下一篇文章,其中將向您展示如何在Linux和Windows上完成。
我認為您的問題可能源於上面的第三點(如果您在Windows上運行),但可能是其他任何原因。
如果您需要執行具有確切順序的線程,則無法使用線程優先級執行此操作。 您可以使用其中一個同步支持。 (例如鎖,信號量)。
我認為正確答案是:您無法通過設置線程優先級來可靠地命令線程啟動。
我認為你的困惑源於文件陳述的事實
具有較高優先級的線程優先於具有較低優先級的線程執行。
雖然這是真的,但它只涉及正在進行計算的線程(或者,在某些操作系統上,等待共享資源)。 在這種情況下,具有較高優先級的線程將獲得更多的CPU時間,即優先於競爭相同資源的線程執行。
即使線程優先級會影響線程的啟動順序(很可能不會),所有線程實際上都可以在現代CPU上並行運行,因為它們不會相互影響。
實際上,執行的順序完全取決於其他因素:線程不進行任何相關計算,它們花費大部分(非常小的)執行時間等待共享資源,即System.out
。
人們必須查看代碼,發現System.out
底層的代碼,即PrintStream
實際上是原子的同步寫入 :
public void write(byte buf[], int off, int len) {
try {
synchronized (this) {
ensureOpen();
out.write(buf, off, len);
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
所以會發生的是,到達println()
的第一個線程阻塞所有其他線程,直到完成寫入其輸出。 無論優先級如何,第一個線程都會卷繞,因為您無法中斷同步塊(這會破壞監視器的用途)。
哪個線程首先獲得鎖定取決於更多因素而不僅僅是線程優先級,甚至可能根本不取決於(Java)線程優先級。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.