#java #concurrency #ehcache
#java #параллелизм #ehcache
Вопрос:
ОБНОВЛЕНИЕ: Все еще озадачен. Я думаю, что единственная возможность заключается в том, что исключение генерируется внутри метода init() после создания потока, но исключение не регистрируется. Я перехватываю все исключения, генерируемые методом create(), и регистрирую их в журнале предупреждений. У кого-нибудь есть теория о том, почему Log4J не сможет печатать мои сообщения журнала? Уровень ведения журнала установлен на ПРЕДУПРЕЖДЕНИЕ.
Я запускаю приложение Spring 3.0, используя EHCache на JBoss. Иногда, когда я запускаю сервер приложений, JVM полностью отключается в течение 20 или 30 секунд. Я настроил его на получение дампа потока каждые 5 секунд и обнаружил, что примерно через 15 секунд дамп начинает экспоненциально увеличиваться с этим же потоком:
"net.sf.ehcache.CacheManager@7d73124b" daemon prio=10 tid=0x00002aac1426a000 nid=0x2300 in Object.wait() [0x00002aac0d886000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00002aaaf5c556e0> (a java.util.TaskQueue)
at java.lang.Object.wait(Object.java:485)
at java.util.TimerThread.mainLoop(Timer.java:483)
- locked <0x00002aaaf5c556e0> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:462)
К моменту завершения работы системы существует около 10 000 потоков, которые выглядят точно так же, как это, только с измененными адресами памяти.
Я провел некоторое исследование и обнаружил, что диспетчер кэша EHCache порождает этот поток в методе init(), который вызывается каждым из его конструкторов. Предполагается, что диспетчер кэша является синглтоном, доступ к которому осуществляется через метод create():
public static CacheManager create() throws CacheException {
if (singleton != null) {
return singleton;
}
synchronized (CacheManager.class) {
if (singleton == null) {
LOG.debug("Creating new CacheManager with default config");
singleton = new CacheManager();
} else {
LOG.debug("Attempting to create an existing singleton. Existing singleton returned.");
}
return singleton;
}
}
Имея дамп потока каждые 5 секунд, я могу видеть трассировки стека по мере размножения этих потоков. Внутри этого блока синхронизации всегда есть один поток, который добрался до конструктора и создаст поток. Тогда всегда есть несколько потоков, ожидающих попадания в синхронизированный блок.
Насколько я могу судить, эта проверка null для синглтона внутри синхронизированного блока должна предотвращать более одной записи в конструктор, но каким-то образом каждый поток, похоже, находит, что синглтон равен null. Я регистрирую все исключения в журнале предупреждений, поэтому я думаю, что если бы исключение создавалось после того, как поток был создан в конструкторе, я бы увидел это в журнале. Я не вижу никаких предупреждений, но я проверил, что это могло бы вызвать такое поведение.
У кого-нибудь есть какие-либо другие идеи, как более одного потока могли бы перейти к этому конструктору? Будет ли java кэшировать проверку null, поскольку она только что проверила null то же поле в предыдущей строке?
Комментарии:
1. Бритва Оккама, вероятно, помогла бы вам
Ответ №1:
Глядя на дамп потока, кажется, что реальной проблемой может быть неисправный таймер, который постоянно порождает потоки, которые обращаются к менеджеру кэша. Думаю, я бы сначала проверил ваш код, чтобы убедиться, что вы не запускаете таймер со временем ожидания 0 (это может быть результатом неправильного вычисления временного смещения).
Комментарии:
1. Даже если существовал таймер, постоянно обращающийся к менеджеру кэша, он реализован как синглтон. Вы должны иметь возможность обращаться к нему столько раз, сколько вам нужно.
Ответ №2:
Если это потоки, порожденные инициализацией менеджера кэша, то, вероятно, это потоки, следящие за обновлением версии на сайте ehcache (хотя я не могу быть уверен). Эти проверки могут быть подавлены либо с помощью свойства времени выполнения Terracotta (я не помню его названия), либо с помощью настройки конфигурации кэша (какой-либо атрибут XML или установщик Spring, в зависимости от того, как определена конфигурация кэша).
Комментарии:
1. Спасибо, но я уже отключил средство проверки обновлений. Это поток, который будет проверять наличие обновлений, но он не указывает на то, как создается так много.
2. Я не знаю, почему так много (никогда такого не было). Но если это поток проверки обновлений, то я думаю (опять же, не уверен), вы можете заблокировать его «создание» (у меня такое ощущение, что один из этих 2 настроек, которые я упомянул в моем ответе, применяется поздно, уже после создания потока).
Ответ №3:
Попытка создать существующий синглтон. Возвращен существующий синглтон.