2010-11-27 5 views
7

Considere una variable de tipo primitivo con muchos hilos de lectura y algunos hilos escribiendo, ¿funcionará correctamente el siguiente código?Mezcla volátil y sincronizada como un bloqueo de lectura y escritura

Si lo hace, ¿ofrece un mejor rendimiento que 1). declarando sincronizado en todos los métodos; 2). usando un ReadWriteLock explícito?

¿Es este un patrón común? Si no, ¿qué patrón se usa generalmente en esta situación?

Esto actualmente funciona bien para mí, pero creo que es un poco redundante usar tanto volátil como sincronizado.

private volatile int value = 1; 

public void func1() 
{ 
    if (value == 1) { 
     // do something 
    } 
} 

public void func2() 
{ 
    if (value == 2) { 
     // do something 
    } 
} 

public void func3() 
{ 
    if (value == 3) { 
     // do something 
    } 
} 

public synchronized void increase() 
{ 
    if (value < 10) value++; 
} 

public synchronized void decrease() 
{ 
    if (value > 0) value--; 
} 

Respuesta

3

Considere la posibilidad de una variable de tipo primitivo con muchos hilos de lectura y algunos hilos de escritura, ¿funcionará correctamente el siguiente código?

Creo que sí.

Si lo hace, ¿ofrece un mejor rendimiento que 1). declarando sincronizado en todos los métodos; 2). usando un ReadWriteLock explícito?

Creo que sí, siempre que las operaciones de lectura excedan en número las solicitudes de escritura. Sin embargo:

  • A menos que este contador sea altamente contencioso, probablemente no importe. No pierdas tu tiempo micro-optimizando algo a menos que tengas evidencia de que es (o será) un cuello de botella.
  • Si realmente te importa, haz una evaluación comparativa.
  • No se sorprenda si el rendimiento relativo depende de las versiones de JVM/niveles de parche, opciones de JVM y hardware; p.ej. cantidad de procesadores y arquitectura de memoria.

¿Es este un patrón común? Si no, ¿qué patrón se usa generalmente en esta situación?

No sé si esto es habitual. Pero mi intuición es que el enfoque más común es simplemente utilizar la sincronización regular, y no preocuparse por eso. A menos que se trate de una estructura de datos altamente controvertida, la diferencia de rendimiento entre los diversos enfoques será insignificante para el rendimiento general de la aplicación.

0

estoy seguro de que proporciona un mejor rendimiento, ya que no hay bloqueo, pero si es correcto depende de la intención del código. Por supuesto, el comportamiento es diferente del caso sincronizado. Si el comportamiento es similar al caso de bloqueo depende de dónde se bloquea.

Cuestiones relacionadas