Problemas de seguridad de subprocesos en la asignación de referencias mediante la llamada al método

Tengo el siguiente código:

class SomeClass {
    private Map<String, String> someMap = null;

    public String getValue(String key) {
        if (someMap == null) {
            someMap = initialize(); // initialize() is some method which returns a proper map.
        }
        return someMap.get(key);
    }
}

Assuming I don't care about someMap getting initialized more than once, are there any other thread-safety issues that I need to be concerned about here.

Según what-operations-in-java-are-considered-atomic , Reference assignment is certainly atmoic. Is the assignment to someMap guaranteed to happen after the method call to initialize() (seems logical to me). Is there any possibility that a thread can see a partially constructed someMap. Does it matter if instead of a map, I have some other type of object.

preguntado el 22 de mayo de 14 a las 18:05

2 Respuestas

El código es no thread-safe. If two threads invoke the method getValue on the same object, it is possible, that one thread sees a partially created someMap.

In order to avoid this problem, you have to remove the data races. The simplest solution is to declare someMap as volatile. The simple rule to remember is: If the code contains no data races, then all executions will appear to be sequentially consistent.

contestado el 22 de mayo de 14 a las 18:05

I don't understand this. Wouldn't the assignment to someMap suceder después initialize returns, as the last operation inside the if block. Given that reference assignment is atmoic, how can the map assigned to someMap be partially created. - Vivek

@Vivek: If we are talking only about one thread, then it's true that the assignment to someMap sucede después initialize returns. However, if we talk about several threads, that's only true if the execution is secuencialmente consistente. Take a look at the Wikipedia article on Consistencia secuencial. - nósido

Thanks, got it now. If I remember correctly, making the variable volatile forces all the local writes to be flushed to the main memory before the assignment to the variable. - Vivek

@Vivek: You are only writing once (or a few times). The overhead for write operations shouldn't matter, and the overhead for volatile reads is low. - nósido

Its not a Thread Safe even if you put volatile because if two threads are called getValue method at a same time, the following scenario can happen

1) Thread 1 & Thread 2 comprobar if (someMap == null) , both will pass and try to reinitialise.

2) Both will reinitialize the reference. Thread 1 return the old reference which one is override by thread 2 .

3) So please refer the link Bloqueo doble comprobado en Singleton

contestado el 23 de mayo de 17 a las 11:05

As i mentioned in the question, I don't care about someMap being initialized multiple times. So your scenario does not apply. - Vivek

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.