Я читал Java Concurrency in Practice последнее время - отличная книга. Если вы считаете, что знаете, как работает параллелизм, но в большинстве случаев вы сталкиваетесь с реальными проблемами, похоже, что 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 частным (как-то я оставил его публичным раньше).
Отличный вопрос.Я уверен, что вы можете добиться правильной синхронизации, не объявляя статичную таблицу. Есть ли причина, синхронизация мудрая, почему вы решили пойти со статикой? – Buhb
Пример, однако, немного беден. Как часто в реальном мире случается, что один и тот же пользователь регистрируется из двух мест одновременно? – BalusC
@ unknown-google: вы правы, _userSessions не обязательно быть статичным с точки зрения синхронизации, я думаю, это просто пример плохого дизайна здесь, так как я уверен, что многие люди скажут;) – lukem00