Edit: я понял, что конструктор для синглтона вызывается несколько раз, поэтому кажется, что классы загружаются более одного раза отдельными загрузчиками классов. Как я могу сделать глобальный синглтон в Tomcat? Я гуглил, но пока не повезло.
У меня есть одноэлементный объект, который я создаю следующим образом:
private static volatile KeyMapper mapper = null;
public static KeyMapper getMapper()
{
if(mapper == null)
{
synchronized(Utils.class)
{
if(mapper == null)
{
mapper = new LocalMemoryMapper();
}
}
}
return mapper;
}
Класс KeyMapper по сути является синхронизированной оболочкой для HashMap, имеющей только две функции: одну для добавления сопоставления и одну для удаления сопоставления. При работе в Tomcat 6.24 на моей 32-битной Windows-машине все работает нормально. Однако при работе на 64-битной машине Linux (CentOS 5.4 с OpenJDK 1.6.0-b09) я добавляю одно сопоставление и распечатываю размер HashMap, используемого KeyMapper для проверки того, что сопоставление добавлено (т. Е. Verify size = 1). Затем я пытаюсь получить сопоставление с помощью другого запроса, и я получаю нулевое значение, и когда я проверял размер HashMap, он был равен 0. Я уверен, что сопоставление не было случайно удалено, так как я закомментировал все вызовы для удаления (и я не использую чистые или любые другие мутаторы, просто получи и положи).
Запросы проходят через Tomcat 6.24 (настроен на использование 200 потоков с минимум 4 потоками), и я передал -Xnoclassgc в jvm, чтобы убедиться, что класс случайно не получает сборщик мусора (jvm также работает в -server Режим). Я также добавил метод финализации в KeyMapper для печати в stderr, если он когда-либо собирает мусор, чтобы убедиться, что он не был мусором.
Я в своем уме и не могу понять, почему в одну минуту есть запись в HashMap, а в следующую нет: (