Я читал Java Concurrency на практике в последнее время - отличная книга. Если вы считаете, что знаете, как работает Concurrency, но в большинстве случаев вы сталкиваетесь с реальными проблемами, похоже, что SWAG - это самое большее, что вы можете сделать, то эта книга, несомненно, прольет некоторый свет на эту тему. Это страшно, как многие вещи могут пойти не так, когда вы пытаетесь обмениваться данными между потоками. Думаю, это заставило меня, наверное, немного сумасшедшим в отношении безопасности потоков. Теперь я обеспокоен тем, что с чересчур большой синхронизацией я могу столкнуться с некоторыми проблемами с жизнеспособностью. Вот фрагмент кода, иллюстрирующий:
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;
}
}
Я попытался все исправить: синхронизированный сборник, построенный в статическом разделе и хранящийся в статической окончательной ссылке для безопасной публикации, блокировка в коллекции (вместо this
- чтобы я не блокировал весь класс кодом живет в) и использует классы атомной оболочки для примитивов. В книге упоминается, что переусердство может также вызвать проблемы, но мне кажется, мне нужно больше времени, чтобы полностью обернуть вокруг себя голову. Как бы вы сделали этот код потокобезопасным и удостоверились, что он не страдает от живучести и проблем с производительностью?
EDIT: превратили его в методы и переменные экземпляра, изначально все было объявлено как статический - плохой, плохой дизайн. Также сделал userSessions частным (как-то я оставил его публичным до этого).