簡體   English   中英

通過設置優先級來執行線程執行

[英]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對線程優先級有很好的討論。 要點是:

  1. 優先事項可能根本沒有效果。
  2. 優先級是指示調度的計算只有一個部分。
  3. 在實踐中可以將不同的Java優先級值轉換為相同的值(例如,優先級10和9可以相同)。
  4. 由於Java正在使用底層操作系統的線程機制,因此每個操作系統都會自行決定如何處理優先級。

請務必閱讀下一篇文章,其中將向您展示如何在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM