2011-02-08 12 views
5

Tengo una pregunta relacionada con los hilos de java.Sincronización de subprocesos de Java, la mejor utilidad concurrente, operación de lectura

Para tomar un ejemplo muy simple, digamos que tengo 2 hilos.

Tema Un ejemplo StockReader clase en curso

Tema B instancia en ejecución StockAvgDataCollector Clase

En Tema B, StockAvgDataCollector recoge algunos mercados de datos de forma continua, hace algo pesada promedio/manipulación y actualiza una variable miembro spAvgData

En el subproceso Un StockReader tiene acceso a la instancia StockAvgDataCollector y su miembro spAvgData utilizando el método getspAvgData().

Por lo tanto, el subproceso A solo funciona con READ y el subproceso B realiza operaciones de LEER/ESCRIBIR.

Preguntas

  1. Ahora, ¿necesito la sincronización o la funcionalidad atómica o de bloqueo o cualquier material relacionado con la concurrencia en este escenario? No importa si el hilo A lee un valor anterior.

  2. Como el hilo A solo va a READ y no actualiza nada y solo el hilo B realiza operaciones de ESCRITURA, ¿habrá situaciones de estancamiento?

He pegado un párrafo a continuación en el siguiente enlace. A partir de ese párrafo, parece que necesito preocuparme por algún tipo de bloqueo/sincronización.

http://java.sun.com/developer/technicalArticles/J2SE/concurrency/

Cerraduras lector/grabador

Cuando se utiliza un hilo para leer datos de un objeto, que no necesariamente tienen que evitar que otro hilo de la lectura de datos al mismo tiempo. Siempre que los hilos solo lean y no cambien datos, no hay razón por la cual no puedan leer en paralelo. El paquete J2SE 5.0 java.util.concurrent.locks proporciona clases que implementan este tipo de bloqueo. La interfaz ReadWriteLock mantiene un par de bloqueos asociados, uno para solo lectura y otro para escritura. El readLock() puede ser retenido simultáneamente por múltiples cadenas de lectores, siempre que no haya escritores. El writeLock() es exclusivo. Si bien, en teoría, está claro que el uso de bloqueos lector/escritor para aumentar la concurrencia conduce a mejoras en el rendimiento sobre el uso de un bloqueo de exclusión mutua. Sin embargo, esta mejora en el rendimiento solo se realizará completamente en un multiprocesador y la frecuencia con que se leen los datos en comparación con la modificación, así como la duración de las operaciones de lectura y escritura.

¿Qué utilidad concurrente sería menos costosa y adecuada en mi ejemplo?

java.util.concurrent.atomic?

java.util.concurrent.locks?

java.util.concurrent.ConcurrentLinkedQueue? - En este caso, StockAvgDataCollector se agregará y StockReader se eliminará. No se expondrá el método getpAvgData().

Gracias Amit

+0

Lo siento, no era consciente. Acabo de aceptar todas mis preguntas anteriores. Gracias por mencionarlo. – FatherFigure

Respuesta

3

Bueno, todo el asunto de ReadWriteLock realmente tiene sentido cuando tienes muchos lectores y al menos un escritor ... Así garantizas la vivacidad (no estarás bloqueando ningún hilo de lector si no hay ningún otro hilo escribiendo). Sin embargo, solo tiene dos hilos.

Si no le molesta que el hilo B lea un valor antiguo (pero no corrupto) de spAvgData, entonces elegiría un AtomicDouble (o AtomicReference, dependiendo del tipo de datos de spAvgData).

Así que el código se vería así

public class A extends Thread { 
    // spAvgData 
    private final AtomicDouble spAvgData = new AtomicDouble(someDefaultValue); 

    public void run() { 
    while (compute) { 
    // do intensive work 
    // ... 
     // done with work, update spAvgData 
    spAvgData.set(resultOfComputation); 
    } 
    } 

    public double getSpAvgData() { 
    return spAvgData.get(); 
    } 
} 
// -------------- 

public class B { 
    public void someMethod() { 
    A a = new A(); 
    // after A being created, spAvgData contains a valid value (at least the default) 
    a.start(); 
    while(read) { 
     // loll around 
     a.getSpAvgData(); 
    } 
    } 
} 
+0

Gracias por todas sus respuestas y creo que todas ellas son buenas y merecen la misma aceptación. Pero stackoverflow permite que solo se acepte una respuesta. – FatherFigure

2
  1. Si no le importa que el hilo puede leer un absurdo completo (incluyendo datos actualizados parcialmente) pues no, no necesita ninguna sincronización. Sin embargo, sospecho que deberías molestarte.
  2. Si solo usa un solo mutex, o ReentrantReadWriteLock y no suspende ni duerme sin tiempo de espera mientras mantiene bloqueados, entonces no habrá interbloqueo. Si realizas operaciones de subprocesos no seguros o intentas rodar tu propia solución de sincronización, entonces tendrás que preocuparte por ello.

Si utiliza una cola de bloqueo, también necesitará un ciclo de ingestión en funcionamiento constante en StockReader. ReadWriteLock todavía es beneficioso para un procesador de núcleo único: los problemas son los mismos ya sea que los subprocesos se ejecuten físicamente al mismo tiempo o simplemente intercalados por conmutadores de contexto.

Si no utiliza al menos alguna forma de sincronización (por ejemplo, volatile), es posible que su lector no vea ningún cambio.

+0

Gracias. Buena información. – FatherFigure

3

Sí, la sincronización es importante y hay que tener en cuenta dos parámetros: visibilidad de la variable spAvgData y atomicidad de su actualización. Para garantizar visibilidad de la variable spAvgData en el hilo B por el hilo A, la variable puede declararse volatile o como AtomicReference. También debe tener en cuenta que la acción de la actualización es atomic en caso de que haya más invariantes o que la acción de actualización sea una acción compuesta, mediante la sincronización y el bloqueo. Si solo el hilo B está actualizando esa variable, entonces no necesita sincronización y la visibilidad debería ser suficiente para que el hilo A lea el valor más actualizado de la variable.

+0

Aunque, por supuesto, Java Spec garantiza que las actualizaciones de int (y más pequeñas) y las referencias son atómicas, por lo que funcionaría una referencia int o objeto volátil, esta última siempre que el escritor * haya reemplazado * el objeto. –

+0

Gracias. Buena información. – FatherFigure

Cuestiones relacionadas