СценарийДолжен ли я использовать ThreadLocal в этом многопоточном сценарии с высоким трафиком?
Мы разрабатываем API, который будет обрабатывать около 2-3 миллионов посещений в час в многопоточной среде. Сервер Apache Tomcat 7.0.64.
У нас есть пользовательский объект с большим количеством данных, назовем его XYZDataContext. Когда приходит новый запрос, мы связываем объект XYZDataContext с контекстом запроса. Один объект XYZDataContext для каждого запроса. Мы будем создавать разные потоки параллельно, чтобы обслуживать этот запрос для сбора/обработки данных из/в объект XYZDataContext. Наши потоки, которые будут обрабатывать вещи параллельно, нуждаются в доступе к этому объекту XYZDataContext и , чтобы избежать прохождения вокруг этого объекта во всем приложении, к различным объектам/методам/потокам, мы думаем сделать его threadlocal. Темы будут использовать данные из объекта XYZDataContext, а также будут обновлять данные в этом объекте. Когда поток заканчивается, мы планируем объединить данные из обновленного объекта XYZDataContext в порожденном дочернем потоке в объект XYZDataContext основного потока.
Мои вопросы:
Является ли это хороший подход?
Связанные с потоком риски - сервер Tomcat будет поддерживать threadpool, и я прочитал, что использование threadlocal с пулами потоков - это катастрофа, потому что поток не GCed за отзыв и повторно используется, поэтому ссылки на объекты threadlocal не получат GCed и будут в хранении огромных объектов в памяти, которые нам больше не нужны, в конечном итоге в результате возникают проблемы с OutOfMemory ...
ОСТАВШИМСЯ, что на них ссылаются как слабые ссылки, чтобы сразу получить GCed.
Мы используем Java 1.7 open JDK. Я видел исходный код для ThreadLocal, и хотяThreadLocalMap.Entry
является слабым отношением, он не связан с ReferenceQueue, а комментарий для конструктора Entry говорит «, поскольку очереди ссылок не используются, занесенные записи гарантированно будут удалены только при запуске таблицы «Я думаю, что это отлично работает в случае с кешами, но это не самое лучшее в нашем случае. Я хотел бы, чтобы объект threadlocal XYZDataContext был немедленно скомпонован. Будет ли эффективен метод
ThreadLocal.remove()
? Есть ли способ принудительно освободить пространство в следующем запуске GC?Это правильный сценарий использования объектов ThreadLocal? Или мы злоупотребляем понятием threadlocal и используем его там, где его не следует использовать?
Все в порядке. Не беспокойтесь о GC, если вы сразу же удалите(). – ZhongYu