Функция устранения проблем с повреждением данных в Tomcat 5.5 и 6.0

2

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

Сервер работает:  - 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.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.

Любые предложения?

  • 0
    См. Базу данных ошибок Sun для ошибки № 4264153 . Классы SimpleDateFormat и связанные с ними форматы не являются потокобезопасными.
  • 0
    Я читал некоторые вопросы о том, что SimpleDateFormat не является поточно-ориентированным, несколько лет назад. Это все еще проблема здесь? Объявляя это как статическую переменную, вызывает ли это повреждение данных, которое кажется очевидным только в Tomcat?
Показать ещё 2 комментария
Теги:
tomcat
centos

1 ответ

5
Лучший ответ

SimpleDateFormat не является потокобезопасным.

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

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

  • создать экземпляр SimpleDateFormat для каждого вызова метода (а не сделать его static)
  • Если вам нужен формат более одного раза для потока, используйте ThreadLocal для его сохранения.
  • альтернативно используйте joda-time, где DateTimeFormat является потокобезопасным.
  • 0
    Спасибо - я думаю, что это решает проблему. Мы используем JODA в других функциях, но не в этом методе, поэтому переход должен быть простым.
  • 0
    да. новый экземпляр каждый раз.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню