2012-02-19 14 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のソースコードを見ると、開始などの重要なすべての方法が同期されます。

is_Aliveは、下位層に実装されたネイティブメソッドであるため、スレッドが開始されたかどうかの瞬時の回答が得られます。同期されていないため、startメソッドが呼び出された後、これは非常にまれですが。

しかし、startメソッドは、操作を進める前にthreadStatusメンバ変数をチェックします。これは揮発性intです。つまり、すべてのアクセススレッドで即座に更新されます。したがって、getState呼び出しを使用して、isAliveメソッドではなくスレッドが開始されているかどうかをチェックして、呼び出しの開始を2回回避することができます。以下の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

* *ネイティブ*メソッドは自動的にスレッドセーフですか?それとも、この場合は*ネイティブ*とスレッドセーフであることだけですか? – Pacerier

+0

すべての関連するメソッドが同期されるため、呼び出しはスレッドセーフです。特にisAlive呼び出しは、JVMの外部にあるので、JVMの他のスレッドとは独立しています。スレッドが生きているかどうかの瞬間的な答えをあなたに与えます。起動直後にisAliveをチェックすると、trueを返さないことがあります。 –

関連する問題