Недавно я прочитал Параллелизм в Java на практике - отличная книга. Если вы думаете, что знаете, как работает параллелизм, но в большинстве случаев сталкиваетесь с реальными проблемами, и вам кажется, что 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
- чтобы я не блокировал весь класс, в котором живет код) и использование атомарные классы-оболочки для примитивов. В книге упоминается, что чрезмерное усердие также может вызвать проблемы, но, похоже, мне нужно еще немного времени, чтобы полностью осознать это. Как сделать этот код потокобезопасным и убедиться, что он не страдает от проблем с живостью и производительностью?
РЕДАКТИРОВАТЬ: превратили его в методы и переменные экземпляра, изначально все было объявлено как статическое - плохой, плохой дизайн. Также сделал userSessions приватным (как-то раньше я оставил его публичным).