2012-03-05 19 views
16

¿Es mala programación inicializar dos hilos con la misma instancia de un ejecutable? ¿Qué diferencia haría inicializar con instancias separadas de un ejecutable, y compartir ubicaciones de memoria para la misma instancia de un ejecutable tiene algo que ver con el rendimiento?Inicializando dos hilos con la misma instancia de un ejecutable

public static void main(String[] args)throws Exception { 
    H h = new H(); 
    H h2 = new H(); 
    Thread j = new Thread(h); 
    j.setName("11"); 

    Thread jj = new Thread(h);//instead of new H() 
    jj.setName("22"); 
    j.start(); 
    jj.start(); 
} 

class H implements Runnable { 
    public void run() { 
     while(true) { 
      System.out.println(Thread.currentThread().getName()); 
     } 
    } 
} 

Respuesta

17

Está absolutamente bien hacerlo siempre que el código que está ejecutando esté diseñado para admitir eso. No solo se ahorrará algo de memoria al tener una sola instancia en lugar de varias instancias, pero si esos hilos son intentando comunicarse a través de datos compartidos, ¡entonces puede ser absolutamente necesario!

Es cierto que la comunicación a través estado compartido es donde enhebrado a menudo se complica, por lo que este necesita ser hecho con cuidado, pero desde el punto de vista del propio sistema de enhebrado, no hay absolutamente ningún problema en tener dos hilos llaman al método de un run instancia única Runnable.

8

Desde H no tiene ningún estado ejemplo, utilizando varias instancias no importa. Debe tener cuidado cuando las instancias Runnable comienzan a almacenar el estado.

public class Main implements Runnable { 
    volatile int i; 
     public void run() { 
     for (i = 0; i < 100; i++) { 
      System.out.println(i); 
     } 
    } 

    public static void main(String[] args) { 
     Main a = new Main(); 
     Thread t1 = new Thread(a); 
     Thread t2 = new Thread(a); 
     t1.start(); 
     t2.start(); 
    }   
} 

¿Qué obtiene printed? Cuando necesite compartir estado entre subprocesos, es una buena idea usar las clases en java.util.concurrent. Fueron escritos principalmente por un experto en multihilo (Doug Lea, autor de Concurrent Programming in Java) y probados por muchas personas. Ahórrate un poco de dolor. :)

+0

woo, todo está jodido. muy interesante –

7

¿Es mala programación inicializar dos hilos con la misma instancia de un ejecutable?

No específicamente. Sin embargo, si la instancia Runnable tiene campos de instancia, entonces deberá asegurarse de que todo el acceso a los campos por el hilo esté sincronizado correctamente, y esto complicará el código.

¿Qué diferencia hay en inicializar con instancias separadas de un ejecutable, y el hecho de compartir ubicaciones de memoria para la misma instancia de un ejecutable tiene algo que ver con el rendimiento?

La memoria almacenada mediante el intercambio de una instancia Runnable entre múltiples hilos es insignificante ... a menos que el Runnable mantiene una cantidad significativa de datos de instancia. (Y si lo hace, lo más probable es que esto hará que la instancia no compartible.)


Su clase H es un ejemplo en casos de uso compartido es seguro, pero tiene sentido ya que el ahorro de memoria es insignificante. (Un objeto Runnable sin campos de instancia ocupa aproximadamente de 8 a 16 bytes, dependiendo de la plataforma.)

0

Para facilitar la comprensión (basado en el comentario de Stephen), se agregó el siguiente bloque de programa sobre el impacto del acceso a la instancia variable de un bloque no sincronizado con la misma instancia de Runnable muestra los resultados inesperados.

public class SynchronizedInstanceMethod implements Runnable{ 

private int counter; 

public SynchronizedInstanceMethod(int counterValue){ 
    this.counter = counterValue; 
} 

private synchronized void displayMessage(){ 
    System.out.println(" Display Message "); 
} 

private void modifyCounter(){ 
    this.counter++; 
    System.out.println("Value -- "+ this.counter); 
} 

@Override 
public void run() { 
    this.displayMessage(); 
    this.modifyCounter(); 
} 

public static void main(String[] args) { 
    SynchronizedInstanceMethod instance = new SynchronizedInstanceMethod(5); 
    new Thread(instance).start(); 
    new Thread(instance).start(); 
} 
} 
Cuestiones relacionadas