Функция устранения проблем с повреждением данных в Tomcat 5.5 и 6.0 - PullRequest
2 голосов
/ 22 апреля 2011

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

Сервер работает: - Tomcat 6 - OpenJDK 1.6.0_17 - CentOS 5.5

У меня есть простой файл класса со следующим методом Статический метод и объявление статической переменной:

public static java.text.SimpleDateFormat displayDateSDF1 = new java.text.SimpleDateFormat("MM/dd/yyyy");

public static java.util.Date getSubDateMini(String inputDate)
{
    java.util.Date testObj = null;
    try
    {
        testObj = displayDateSDF1.parse("01/01/2000") ;
    }
    catch (Exception e)
    {
    }
    return testObj;
}

Тестирование в Tomcat:

Когда я запускаю этот метод, я ожидаю, что каждый раз получаю один и тот же результат, верно?Однако, если я вызываю этот метод из JSP, я получаю ожидаемый результат объекта Date со значением 1/1/2000 примерно в 99,9% случаев.Тем не менее, иногда я получаю неожиданный объект данных, передаваемый обратно с на первый взгляд случайным значением даты.

Чтобы проверить это, я создал JSP со следующим сегментом кода:

for (int i=0; i<200000;i++)
{
    java.util.Date testObjLib = TestDate.getSubDateMini("") ;
    if (testObjLib!=null&&!testObjLib.toString().equalsIgnoreCase("Sat Jan 01 00:00:00 PST 2000"))
    {
            out.print("<br>"+testObjLib+"");
    }
}

Ниже приведены некоторые даты:

Ср Ян01 00:00:00 PST 1

Пт Авг 01 00:00:00 PDT 2166

В 200 000 пробежек я получаю примерно 50 неудачных дат, которыедает ошибку ~ 0,025%, но опять-таки это случайно.Я запустил этот цикл с 10 итерациями и получил ошибку.Иногда он запускает цикл с 200 000, и все даты выглядят хорошо.

Тестирование в Java:

Запуск этого цикла через консольное / терминальное приложение в CentOS с таким же циклом, я еще не видел, чтобы эта ошибка произошла.Я увеличил цикл до 10 000 000 и пока не дал ложных результатов.


Я могу понять, что недостаточно памяти или какая-то ошибка (которая может привести к нулевому значению), но не поврежденные / противоречивые данные.Я создал новый сервер с помощью Tomcat 6, а также попробовал Tomcat 5.5, и оба получили одинаковые результаты.Я не пробовал Tomcat 7.

Есть предложения?

1 Ответ

5 голосов
/ 22 апреля 2011

SimpleDateFormat не является поточно-ориентированным.

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

У вас есть несколько вариантов:

  • создает SimpleDateFormat при каждом вызове метода (а не делает его static)
  • если вам нужен формат более одного раза для потока, используйте ThreadLocal для его сохранения.
  • альтернативно используйте joda-time, где DateTimeFormat потокобезопасен.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...