2012-02-19 65 views
7

我想知道我們是否需要外部同步來使用java.lang.Thread中的方法?java.lang.Thread本身是一個線程安全的類嗎?

例如,我們可以調用的方法t1.isAlive()任何線程沒有外部同步,並期望它返回:

真,如果T1已經開始,否則爲false。

或者需要外部同步來調用java.lang.Thread中的方法嗎?

public static void main(String args[]) { 
     final java.lang.Thread t1 = new java.lang.Thread(new java.lang.Runnable() { 

      @Override 
      public void run() { 
       while(true){ 
        //task 
       } 
      } 
     }); 
     java.lang.Thread t2 = new java.lang.Thread(new java.lang.Runnable() { 

      @Override 
      public void run() { 
       while (true) { 
        System.out.println(t1.isAlive()); // do we need synchronization before calling isAlive() ? 
       } 
      } 
     }); 
     t2.start(); 
     t1.start(); 
     try { 
      java.lang.Thread.sleep(1000000); 
     } catch (java.lang.InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

回答

4

是的,它應該已經是線程安全的。你可以看看Thread.java here的源代碼,所有重要的方法如start等都是同步的。

is_Alive是一個在較低層實現的本地方法,因此會立即給出線程是否啓動的答案,它不會被同步,因此它可能在調用start方法後給出錯誤的權限。雖然這非常罕見。

然而,start方法在繼續進行操作之前檢查了threadStatus成員變量,這是一個易失性int,即將跨所有訪問線程立即更新。因此,您可以使用getState調用來檢查線程是否啓動,而不是isAlive方法,以避免調用兩次。我已經複製下面的Thread.java的相關部分。

/* Java thread status for tools, 
* initialized to indicate thread 'not yet started' 
*/ 

private volatile int threadStatus = 0; 

... 

public synchronized void start() { 
    /** 
    * This method is not invoked for the main method thread or "system" 
    * group threads created/set up by the VM. Any new functionality added 
    * to this method in the future may have to also be added to the VM. 
    * 
    * A zero status value corresponds to state "NEW". 
    */ 
    if (threadStatus != 0) 
     throw new IllegalThreadStateException(); 
.... 

public State getState() { 
    // get current thread state 
    return sun.misc.VM.toThreadState(threadStatus); 
} 
+1

你是說* * native *方法是自動線程安全的嗎?或者它僅僅是在本例中是* native *和線程安全的? – Pacerier 2012-02-19 04:45:29

+0

該調用通常是線程安全的,因爲所有相關的方法都是同步的。特別是對於isAlive調用,因爲它是JVM外部的,它獨立於JVM中的其他線程。它會給你一個線程是否存活的即時答案。請注意,如果您在啓動後檢查isAlive,它可能不會返回true。 – 2012-02-19 04:50:52