Как мой ThreadLocal сбрасывается при каждом запросе, даже если у нас есть пул потоков

Я заметил кое-что интересное.

Мне сказали (и из того, что я читал), что безопасно хранить переменные области запроса в ThreadLocal (допустим, у вас нет доступа к объекту запроса и вы не можете использовать атрибуты запроса)

Что ж, похоже, это работает (по крайней мере, когда я проверил Tomcat). например Даже если у меня в пуле 10 потоков, кажется, что локальные переменные потока существуют только в рамках одного запроса. Я имею в виду, даже если я вижу одно и то же имя потока (скажем, у меня их 10 в пуле, поэтому после 10 запросов я должен увидеть несколько повторений), каждый запрос "волшебным образом" сбрасывает все локальные переменные потока для этого потока.

Это правда?

Каждый раз, когда поток запроса возвращается в пул, он очищает все локальные переменные потока? Как?


person Eran Medan    schedule 01.05.2015    source источник
comment
Возможно, связано: stackoverflow.com/ questions / 7403809 /   -  person    schedule 01.05.2015
comment
Это будет зависеть от контейнера. Принцип ThreadLocal диктует, что конструкция многоразовая. Как будет действовать конкретный контейнер, зависит от этого контейнера.   -  person kolossus    schedule 01.05.2015


Ответы (2)


В более поздних версиях tomcat есть механизм локальной защиты потока, чтобы избежать утечек памяти и, в частности, защитить от зависания загрузчиков классов при повторном развертывании приложения.

TC 6.0.24 обнаруживает это, а 7.0.6 удаляет локальные переменные потока, как описано здесь: http://wiki.apache.org/tomcat/MemoryLeakProtection

Так что это не нормально для потоков / пулов потоков, это функция TC.

person eckes    schedule 01.05.2015

Каждый раз, когда поток запроса возвращается в пул, он очищает все локальные переменные потока?

Кажется, что Tomcat позаботился о уборке дома, но в целом ответ отрицательный, и это было одной из причин, по которым возникали ошибки Out Of Memory в Glassfish 3.0.1

В Glassfish 3.0.1, например, во время развертывания приложения некоторый код создавал переменную ThreadLocal, содержащую ссылку на некоторые экземпляры, которая, в свою очередь, похоже, содержит ссылку на множество других объектов (в основном связанных с прокси-классами, созданными во время развертывания EJB и CDI. ). Похоже, что Glassfish не очищает эту ссылку после завершения развертывания, что не будет большой проблемой, если поток, развертывающий приложение, завершится.

К сожалению, поток развертывания приложения никогда не завершается, потому что он не создается исключительно для целей развертывания приложения. Вместо этого он берется из пула потоков Glassfish, и ожидаемое поведение возвращается в пул после завершения задачи развертывания. Это означает, что ссылка ThreadLocal никогда не очищается и со временем приводит к переполнению кучи.

person sol4me    schedule 01.05.2015