He estado leyendo Java Concurrency in Practice últimamente - gran libro. Si crees que sabes cómo funciona la concurrencia, pero la mayoría de las veces te enfrentas a problemas reales, parece que SWAG es lo máximo que puedes hacer, entonces este libro arrojará algo de luz sobre el tema. Es un poco aterrador cómo muchas cosas realmente pueden salir mal cuando intentas compartir datos entre hilos. Supongo que eso me hizo estar un poco loco por la seguridad de los hilos. Ahora mi preocupación es que, con un poco de sincronización, puedo encontrarme con algunos problemas de vida. He aquí un fragmento de código para ilustrar:¿Cuánta seguridad de hilo es demasiado?
private final Hashtable<String, AtomicInteger> userSessions =
new Hashtable<String, AtomicInteger>();
public void registerUser(String userLogin) {
synchronized(userSessions) {
AtomicInteger sessionCount = userSessions.get(userLogin);
if (sessionCount != null) {
sessionCount.incrementAndGet();
} else {
userSessions.put(userLogin, new AtomicInteger(1));
}
}
}
public void unregisterUser(String userLogin) {
synchronized(userSessions) {
AtomicInteger sessionCount = userSessions.get(userLogin);
if (sessionCount != null) {
sessionCount.decrementAndGet();
}
}
}
public boolean isUserRegistered(String userLogin) {
synchronized(userSessions) {
AtomicInteger sessionCount = userSessions.get(userLogin);
if (sessionCount == null) {
return false;
}
return sessionCount.intValue() > 0;
}
}
He intentado conseguir que bien: sincronizada colección construido en la sección estática y se almacena en una referencia static final para su publicación segura, bloqueo para la recogida (en lugar de this
- de manera que No bloqueo toda la clase en la que vive el código) y el uso de clases de envoltura atómica para primitivos. El libro menciona que exagerar esto también podría causar problemas, pero parece que necesito más tiempo para entenderlo. ¿Cómo harías que este código fuera seguro para subprocesos y asegúrate de que no sufra problemas de vida y de rendimiento?
EDIT: Lo convirtió en métodos de ejemplo y variables, originalmente todo se declaró como estático - mal, mal diseño. También hizo userSessions privada (de alguna manera la dejé pública antes).
Excelente pregunta.Estoy seguro de que puede lograr una sincronización adecuada sin declarar la tabla estática. ¿Hay alguna razón, sincronización correcta, por qué elegiste ir con estática? – Buhb
El ejemplo es, sin embargo, un poco pobre. ¿Con qué frecuencia ocurriría en el mundo real que el mismo y único usuario está iniciando sesión desde dos lugares al mismo tiempo? – BalusC
@ unknown-google: Tiene razón, _userSessions no necesita ser estático desde el punto de vista de la sincronización, supongo que es solo un ejemplo de diseño pobre aquí, como estoy seguro que mucha gente diría;) – lukem00