Pregunta

Leyendo algunos hilos ( problemas comunes de concurrencia , palabra clave volátil , modelo de memoria ) Estoy confundido acerca de los problemas de concurrencia en Java.

Tengo muchos campos a los que se accede por más de un hilo. ¿Debo revisarlos y marcarlos como volátiles?

Al crear una clase, no sé si múltiples subprocesos accederán a ella, por lo que seguramente no es seguro permitir que cualquier campo no sea volátil, por lo que, según tengo entendido, hay muy pocos casos en los que no. No lo uses. ¿Esto es correcto?

Para mí, esto es específico de la versión 1.5 JVM y posteriores, pero no se siente limitado a responder sobre mi configuración específica.

¿Fue útil?

Solución

Si varios subprocesos acceden a un campo, debe ser volatile o final , o solo se debe acceder a ellos con bloques sincronizados. De lo contrario, los valores asignados pueden no ser visibles para otros subprocesos.

Una clase debe estar diseñada específicamente para el acceso simultáneo por varios subprocesos. El simple hecho de marcar los campos como volátil o final no es suficiente para la seguridad de los hilos. Hay problemas de coherencia (atomicidad de los cambios en múltiples campos), inquietudes sobre la señalización entre subprocesos (por ejemplo, utilizando wait y notificar ), etc.

Por lo tanto, es más seguro asumir que un objeto debe ser visible solo para un solo hilo a menos que esté documentado de otra manera. Hacer que todos sus objetos sean seguros para el subproceso no es necesario, y es costoso & # 8212; en términos de velocidad del software, pero lo más importante, en términos de gastos de desarrollo.

En su lugar, el software debe diseñarse de modo que los subprocesos concurrentes interactúen entre sí lo menos posible, preferiblemente de ninguna manera. Los puntos en los que interactúan deben identificarse claramente para que se puedan diseñar los controles de concurrencia adecuados.

Otros consejos

Bueno, has leído esas otras preguntas y supongo que ya has leído las respuestas, así que solo resaltaré algunos puntos clave:

  1. van a cambiar? Si no es así, no necesitas volátiles.
  2. en caso afirmativo, ¿el valor de un campo está relacionado con otro? Si es así, vaya al punto 4
  3. ¿cuántos hilos lo cambiarán? si solo es 1, entonces volátil es todo lo que necesita
  4. si la respuesta al número 2 es " no " o más de un subproceso va a escribir en él, por lo tanto, volátil solo es insuficiente , probablemente necesitará sincronizar el acceso

Añadido:
Si el campo hace referencia a un Objeto, tendrá campos propios y todas esas consideraciones también se aplican a estos campos.

Si tiene que preguntar, use candados. volatile puede ser útil en algunos casos, pero es muy, muy difícil hacerlo bien. Por ejemplo:

class Foo {
  private volatile int counter = 0;
  int Increment() {
    counter++;
    return counter;
  }
}

Si dos subprocesos ejecutan Incremento () al mismo tiempo, es posible que el resultado sea contador = 1 . Esto se debe a que la computadora primero recuperará counter , agregará uno y luego lo guardará. La volatilidad solo obliga a que se guarden y se carguen en un orden específico en relación con otras declaraciones.

Tenga en cuenta que sincronizado generalmente evita la necesidad de volatile : si todos los accesos a un campo determinado están protegidos por el mismo monitor, volatile nunca será necesario.

Utilizar volatile para hacer algoritmos sin bloqueo es muy, muy difícil; apégate a sincronizado a menos que tengas pruebas sólidas de que ya sea demasiado lento y hayas realizado un análisis detallado del algoritmo que planeas implementar.

La respuesta corta es no. Temas de hilos requieren más reflexión y planificación que esto. Consulte esto para conocer algunas limitaciones sobre cuándo ayuda volátil para Roscado y cuando no lo hace. La modificación de los valores debe estar correctamente sincronizada, pero en general la modificación requiere el estado de más de una variable a la vez. Digamos, por ejemplo, que tiene una variable y desea cambiarla si cumple con un criterio. La lectura de la matriz y la escritura en la matriz son instrucciones diferentes y deben sincronizarse juntas. Lo volátil no es suficiente.

Considere también el caso en el que la variable hace referencia a un objeto mutable (por ejemplo, una matriz o una Colección), luego, interactuar con ese objeto no será seguro para subprocesos solo porque la referencia es volátil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top