2012-02-19 9 views
7

Me preguntaba si requerimos sincronización externa para usar los métodos en java.lang.Thread?¿Es java.lang.Thread una clase segura para subprocesos?

Por ejemplo, podemos llamar al método t1.isAlive() de cualquier hilo sin sincronización externa y esperar que volver:

cierto si t1 ya se ha iniciado, en caso contrario.

¿O es necesaria una sincronización externa para llamar a los métodos en 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(); 
     } 
    } 

Respuesta

4

Sí, ya debería ser seguro para subprocesos. Puede consultar el código fuente de Thread.java here, todos los métodos importantes, como inicio, etc., están sincronizados.

is_Alive es un método nativo implementado en una capa inferior por lo que dará una respuesta instantánea si el hilo se inicia o no, no está sincronizado por lo que puede dar un falso derecho después de que se llame al método de inicio. Aunque esto es muy raro.

El método de inicio, sin embargo, verifica la variable miembro de threadStatus antes de continuar con su operación y esto es una información volátil, es decir, se actualizará instantáneamente en todos los hilos de acceso. De modo que puede usar la llamada getState para verificar si se inicia un hilo en lugar del método isAlive para evitar el inicio de la llamada dos veces. He copiado las partes relevantes de Thread.java a continuación.

/* 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

¿Está diciendo que un método * native * es automáticamente seguro para subprocesos? ¿O es simplemente que es tanto * nativo * como seguro para subprocesos en este caso? – Pacerier

+0

La llamada es segura para subprocesos en general porque todos los métodos pertinentes están sincronizados. Específicamente para la llamada isAlive ya que es externa a la JVM, es independiente de los otros hilos en la JVM. Le dará una respuesta instantánea de si el hilo está vivo o no. Tenga en cuenta que si marca isAlive inmediatamente después del inicio, puede que no sea verdadero. –

Cuestiones relacionadas