ОБНОВЛЕНИЕ: Все еще озадачен.Я думаю, что единственная возможность - это исключение, которое выдается внутри метода init () после того, как поток порожден, но исключение не регистрируется.Я перехватываю все исключения, созданные в методе create (), и записываю их в журнал предупреждений.У кого-нибудь есть теория о том, почему Log4J не сможет печатать мои сообщения журнала?Уровень ведения журнала установлен на WARN.
Я запускаю приложение 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)
К тому времени, когда система выключается, появляютсяоколо 10000 потоков, которые выглядят точно так же, только с измененными адресами памяти.
Я провел некоторое исследование и обнаружил, что EHCache Cache Manager порождает этот поток в методе init (), который вызывается каждым из его конструкторов.Предполагается, что Cache Manager - это одноэлементный объект, доступ к которому осуществляется с помощью метода 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 секунд, я могу видеть трассировки стека по мере их увеличения.Внутри этого блока синхронизации всегда есть один поток, который дошел до конструктора и создаст поток.Тогда всегда есть несколько потоков, ожидающих входа в синхронизированный блок.
Насколько я могу судить, эта проверка нуля на singleton внутри синхронизированного блока должна предотвращать более одного входа в конструктор, но каким-то образом каждый поток обнаруживает singleton быть нулевым.Я записываю все исключения в журнал предупреждений, поэтому думаю, что если после создания потока в конструкторе было создано исключение, я бы увидел его в журнале.Я не вижу никаких предупреждений, но я проверил, что это может вызвать такое поведение.
Есть ли у кого-нибудь еще идеи о том, как более одного потока может попасть в этот конструктор?Будет ли Java кешировать нулевую проверку, так как она только что провела проверку на то же поле в предыдущей строке?