Comments 8
SystemUtils — это чей класс? можно в код добавить import для классов?
0
SystemUtils свой класс. Добавил код под спойлер.
0
private static ConcurrentHashMap<Long, Long> threadToPersonID = new ConcurrentHashMap<Long, Long>();
Лучше использовать ThreadLocal:
ThreadLocal<Long> userId = = new ThreadLocal<>()
+2
Сегодня один умный человек с Хабра, который по каким-то причинам не может писать комментарии, заметил две важные проблемы, которые стоит иметь ввиду.
1) Стоит иметь ввиду, что в web приложениях используется пул потоков — потоки не уникальны. Данное решение будет работать, но только за счёт того что ThreadLocal каждый раз инициализируется заново.
2) Если Thread получит interrupt — блок finally не выполнится. Если работу с базой данных всегда производить через FakeOwnerTransaction.start() — всё будет хорошо, иначе getFakeChanger() может вернуть неверное значение вместо null. Конечно вероятность ошибки крайне мала, но необходимо понимать её возможность.
Добавил замечания в шапку.
1) Стоит иметь ввиду, что в web приложениях используется пул потоков — потоки не уникальны. Данное решение будет работать, но только за счёт того что ThreadLocal каждый раз инициализируется заново.
2) Если Thread получит interrupt — блок finally не выполнится. Если работу с базой данных всегда производить через FakeOwnerTransaction.start() — всё будет хорошо, иначе getFakeChanger() может вернуть неверное значение вместо null. Конечно вероятность ошибки крайне мала, но необходимо понимать её возможность.
Добавил замечания в шапку.
0
1 — не совсем понятен комментарий.
Решение не будет работать если не инициализировать ThreadLocal и будет если инциализировать, и это не связано с тем откуда у нас тред. То что у нас повсеместно треды переиспользуются, означает что крайне важно сбрасывать ThreadLocal когда он не нужен (и с точки зрения корректности и с точки зрения memory leak-ов).
2 — не верно.
С interrupted-тредами возможны два состояния
1) у треда стоит статус «interrupted»
2) выпал «InterruptedException» (или подобное исключение)
В первом случае с потоком исполнения ничего не происходит пока не произойдет вызов некоторых методов или блокирующего i/o. Вообще говоря тред может и не заметить что он «прерван» до вызова определенных методов. И в таком случае, после завершения try блока, произойдет нормальное исполнение finally блока.
Решение не будет работать если не инициализировать ThreadLocal и будет если инциализировать, и это не связано с тем откуда у нас тред. То что у нас повсеместно треды переиспользуются, означает что крайне важно сбрасывать ThreadLocal когда он не нужен (и с точки зрения корректности и с точки зрения memory leak-ов).
2 — не верно.
С interrupted-тредами возможны два состояния
1) у треда стоит статус «interrupted»
2) выпал «InterruptedException» (или подобное исключение)
В первом случае с потоком исполнения ничего не происходит пока не произойдет вызов некоторых методов или блокирующего i/o. Вообще говоря тред может и не заметить что он «прерван» до вызова определенных методов. И в таком случае, после завершения try блока, произойдет нормальное исполнение finally блока.
+1
Абсолютно верно. Спасибо за подробное разъяснение. По первому — просто неудачно выразился. По поводу interrupted действительно не правильно сказал, меня самого запутали. Поток может быть завершен извне JVM, в этом случае блок finaly не будет выполнен. Гипотетически это может привести к утечке памяти, но меня данное решение устраивает.
0
Sign up to leave a comment.
Hibernate envers. Подмена ID пользователя совершившего изменение