2016-11-26 115 views
1

我有一個方法線程同步執行操作順序

public static synchronized void print(String message, int sleepTime) throws InterruptedException { 
    System.out.println(message); 
    Thread.sleep(sleepTime); 
} 

調用此方法打印任何消息,我給它,並導致調用它來暫停指定的時刻線程。該static synchronized使得它使這一類的多線程必須同步他們的print以便完成另一個線程之前睡覺(除了第一個線程調用,當然print)沒有線程可以開始打印

別的地方在我的代碼,我有調用線程這樣做:

print("some message", 1000); 
print("some other message", 1000); 

每個審判我已經使用這個代碼運行導致打印的第一條消息「一些信息」第一,其次是印刷「一些其他信息」最後所有線程的所有線程。

舉例來說,如果我有3個線程,預期結果如下(我可以讓他們當我運行了幾次代碼):

some message 
some message 
some message 
some other message 
some other message 
some other message 

誠然,我還沒有運行許多試驗。但是,我懷疑一個完成打印第一條消息(讓我們調用這個線程A)的線程將與可能還沒有打印第一條消息的其他線程(讓我們稱之爲這樣的線程B)競爭。 是否有可能的是,調度程序挑選的拾取乙用於第一時間,從而使所述第二消息之前的第二時間在某處被所述第一消息的所有實例都完成打印之前打印?

換句話說,是有可能,這可能發生:

some message 
some message 
some other message 
some message 
some other message 
some other message 

如果上面的序列是可能的,我怎麼能保證它不發生?我如何保證第一個序列是總是發生的序列?

+0

你說的第一順序是什麼意思?你最後兩個問題都是矛盾的嗎? – developer

+0

第一序列,我的意思是打印所有「一些消息」行之前打印所有「一些其他消息」行。第二個序列是具有交換消息的序列。我指的是每個代碼塊的一個序列。 – Manuel

+0

好的,但你爲什麼要這麼做?目標不是很清楚。 – developer

回答

2

這取決於你的意思是可能的。絕對沒有禁止它的規則。但是,您正在使用的實現中所做的特定設計選擇可能會導致實際上無法實現。

1

是否有可能的是,調度程序挑選的拾取 乙用於第一時間,從而使所述第二消息之前的第二時間要打印 某處所述第一消息的所有實例都完成 打印前?

是的,這是可能的,線程調度器可以再次選擇相同的線程。

此外,還有一個參數,你可能會感興趣,你需要仔細檢查的是兩個線程的優先級相同的或不,這可能會導致線程匱乏的解釋here,這導致同一線程運行一次又一次。只需添加,您可以通過調用setPriority(int newPriority)將優先級設置爲Thread,如API here中所示。

+0

該鏈接不適合我,但我想我知道你在做什麼。基本上,如果在調度程序選擇的任何隊列中始終存在具有較高優先級線程的流,那麼優先級較低的線程將永遠不會運行,對吧? – Manuel

+0

我已經更新了鏈接,它現在可用 – developer

1

這絕對是可能的。我運行了一個簡單的多線程程序,它有3個線程,我確實得到了你想要的互鎖消息。

public class ThreadSyncTest { 

    public static void main(String[] args) { 

     ThreadSyncTest t = new ThreadSyncTest(); 
     TempThread r1 = t.new TempThread(); 
     Thread t1 = new Thread(r1); 

     TempThread r2 = t.new TempThread(); 
     Thread t2 = new Thread(r2); 

     TempThread r3 = t.new TempThread(); 
     Thread t3 = new Thread(r3); 

     t1.start(); 
     t2.start(); 
     t3.start(); 

    } 

    public static synchronized void print(String message, int sleepTime) throws InterruptedException { 
     System.out.println(message); 
     Thread.sleep(sleepTime); 

    } 

    class TempThread implements Runnable{ 

     @Override 
     public void run() { 
      while(true){ 
       try { 
        print("some message", 1000); 
        print("some other message", 1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 

    } 


} 

結果:

some message 
some message 
some other message 
some message 
some other message 
some message 
some message 
some other message 
some message 
some other message