El siguiente código causará los mismos problemas, si la variable 'commonSet' de este método fuera un campo de nivel de clase. Si se tratara de un campo de nivel de clase, tendré que ajustar agregar a la operación de configuración dentro de un bloque sincronizado ya que HashSet no es seguro para subprocesos. ¿Debo hacer lo mismo en el siguiente código, ya que varios hilos se están agregando al conjunto o incluso el hilo actual puede continuar mutando el conjunto.Thread Safe: ¿variable de método local final transferida a los hilos?
public void threadCreatorFunction(final String[] args) {
final Set<String> commonSet = new HashSet<String>();
final Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
commonSet.add(newValue());
}
}
};
new Thread(runnable, "T_A").start();
new Thread(runnable, "T_B").start();
}
La referencia a 'commonSet' está 'bloqueada' mediante el uso de final. Pero múltiples hilos que operan en él aún pueden corromper los valores en el conjunto (¿puede contener duplicados?). En segundo lugar, la confusión es porque 'commonSet' es una variable de nivel de método - es la misma referencia en la memoria de pila del método de llamada (función threadCreator) y la memoria de pila de los métodos de ejecución - ¿es correcto?
Hay un buen número de preguntas relacionadas con esta:
- Why do variables passed to runnable need to be final?
- Why are only final variables accessible in anonymous class?
Pero, no puedo verlos haciendo hincapié en la rosca caja parte de ese intercambio/paso del mutables.
Véase también http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen – nos