2012-11-05 186 views
1

比方說,我們有這樣的場景:在運行時執行順序

class Stack{ 

public void main{ 

ChildThread1 t1 = new ChildThread1; 
ChildThread1 t2 = new ChildThread1; 
ChildThread1 t3 = new ChildThread1; 

//then we make some ChildThread2 objects and some ChildThread3 objects 

ChildThread2 s1 = new ChildThread2; 
//... 

ChildThread3 v1 = new ChildThread3; 
//... 

//now we let all threads start in mix order 
t1.start(); 
v1.start(); 
//... 

SOP("All threads are ready"); 

//then we let them run with join() 
t1.join(); 
t2.join(); 
t3.join(); 

s1.join(); 
//... 

v1.join(); 
//... 

每種類型的線程打印自己獨特的聲明。

我注意到,每次執行程序時,輸出總是不一樣。例如,來自ChilThread1 t1的語句將在輸出中間打印而不是開始(因爲t1首先啓動)或語句「所有線程已準備就緒」將在線程執行的中間彈出(例如:ChildThread2是'所有線程都準備就緒「運行)

所以我試圖找到答案,我發現這個網站:http://www.avajava.com/tutorials/lessons/how-do-i-use-threads-join-method.html 該網站基本上說,有執行的禁擔保令,當您使用的start()

所以我是正確的假設這奇怪的打印順序是因爲start()不保證執行順序?這個原因是否也適用於'所有線程都準備好'的問題?

+0

'新ChildThread1'它應該是'新ChildThread1()' –

+1

我永遠不瞭解這些問題。如果你想或者期望執行某個特定的順序,你爲什麼要使用線程?如果你不知道它們是幹什麼的,你爲什麼使用線程? – EJP

+1

@EJP每個人都必須在某個點上學習。爲什麼要敵對?用一種教他新東西的方式回答他的問題。 –

回答

1

所以我正確地認爲這個奇怪的打印順序是因爲start()不保證執行順序?

是的。你是對的。

這個原因是否也適用於'所有線程都準備好'的問題?

是的。再來一次。您的SOP由主線程運行。因此,有可能t1可以在main得到執行它的機會SOP之前打印一些內容。

+0

謝謝。 '所有線程都準備好'的部分在不同的地方打印出來讓我覺得有些問題。 – user977151

+0

這種類型的輸出意味着它不是原子嗎? – user977151

+0

@ user977151:你在這裏的原子是什麼意思? – Azodious

1

當你啓動一個線程時,啓動的線程並行運行所有已經運行的線程。線程調度程序在可用的處理器上分派各種線程,每個線程獲取一些處理器時間,每個線程輪流處理。但是分配給每個線程的處理器,順序和時間取決於操作系統線程調度程序,並且您絕對不能保證。

3

線程的要點是它們可以同時執行。如果你想確保事情完成的具體順序,你必須擺脫使用線程或使用顯式同步。

所以我正確地認爲這種奇怪的打印順序是因爲start()不保證執行順序?

沒錯。當你使用線程時,主線程和新創建的線程之間基本上存在競爭條件。這意味着對於在兩個線程之間發生事件的相對順序沒有任何可說的。如果你想確保特定的順序,請使用同步。

+0

感謝您的評論。我不希望這個例子的具體順序,我認爲它會在我看到那篇文章之前按順序打印。 – user977151

1

保持線程執行順序簡單的方法是使用旗語

public class Semaphore { 

int value; 

public Semaphore(int intialValue) { 
    this.value = intialValue; 
} 

public synchronized void p() { 
    while (value <= 0) { 
     try { 
      this.wait(); 
     } catch (InterruptedException e) { 
     } 

    } 
    value = value - 1; 
} 

public synchronized void v() { 
    value = value + 1; 
    this.notify(); 
} 

}

public class ThreadSync { 

static Semaphore semaphore = new Semaphore(0); 

public static void main(String[] args) { 
    // t1 should be executed before t2 
    Thread t1 = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      semaphore.p(); 
      System.out.println("executing " + Thread.currentThread().getName()); 
     } 
    }); 
    Thread t2 = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      System.out.println("executing " + Thread.currentThread().getName()); 
      semaphore.v(); 
     } 
    }); 

    t1.setName("Thread 1"); 
    t2.setName("Thread 2"); 
    t2.start(); 
    t1.start(); 

} 

}