Pregunta de entrevista:
¿El siguiente método es seguro para subprocesos?
class MyCounter {
private static int counter = 0;
public static int getCount() {
return counter++;
}
}
En primer lugar, la respuesta es NO. El método no es seguro para subprocesos, porque la operación counter ++ no es atómica, lo que significa que consta de más de una operación atómica.
En este caso, uno hilo accede al valor y el otro aumenta el valor en uno.
Cuando el subproceso 1 accede al método en t1, el subproceso 2 no se puede hacer con el método, por lo tanto, el valor devuelto al subproceso 1 es el valor que no se ha aumentado.
Los podemos ver mas claramente en el siguiente ejemplo:
¿Que debemos tener en cuenta a la hora de programar usando multiples hilos?
- Nunca manipular variables de instancia sin un mecanismo que asegure operaciones atómicas.
- Si accedemos a un metodo que manipula una variable de instancia dicho metodo debe ser declarado con el modificador "synchronized" de manera tal que nos aseguremos que un sólo
subproceso a la vez pueda acceder a la funcion.La palabra synchronized indica que un método puede ser accedido por un solo hilo a la vez. Synchronized puede ser aplicado solo a métodos, ni a variables, ni a clases, solo a métodos. Un ejemplo típico de synchronized sería parecido a esto:
Deberíamos tambien saber que el modificador synchronized puede ser complementado con cualquiera de los 4 niveles de control de acceso.12publicsynchronizedRecord retrieveUserInfo(intid){} - Usar objetos y rutinas de java que aseguren que nuestro programa sea thread safe por ejemplo:
- ConcurrentHashMap:
- Mantendrá el bloqueo a nivel de segmento. Tiene 16 segmentos y mantiene el nivel de concurrencia como 16 por defecto. Entonces, a la vez, 16 subprocesos pueden funcionar en ConcurrentHashMap. Además, la operación de lectura no requiere un bloqueo. Entonces, cualquier número de subprocesos puede realizar una operación de obtención en él.Si thread1 quiere realizar la operación put en el segmento 2 y thread2 quiere realizar la operación put en el segmento 4, entonces está permitido aquí. Significa que 16 subprocesos pueden realizar operaciones de actualización (put / delete) en ConcurrentHashMap a la vez.Para que el tiempo de espera sea menor aquí. Por lo tanto, el rendimiento es relativamente mejor que el Hashmap sincronizado.
El siguiente grafico describe que mapas son seguros y cual es su performance/tipo de acceso:
Como podemos ver en el grafico, el concurrentHashMap funciona con segmentos, el lockeo de hilos es siempre a nivel segmento, lo que permite concurrencia en tiempos de ejecución y mejora considerablemente la performance de un mapa sincronizado o de una rutina que utilice el modificador de sincronización.



