как улучшить поведение пула потоков tomcat

Я запускаю java-приложение, используя tomcat7. Мне нужно хранить информацию для каждого потока tomcat, поэтому я могу использовать подход ThreadLocals.

В моем server.xml определение пула потоков выглядит следующим образом:

 <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" 
    maxThreads="10000" minSpareThreads="2000"/>

У меня есть класс EnhanceThread

public class EnhanceThread extends Thread {
    ...
    @Override
    public void run() {
       SomeThreadLocals.set(data);
       super.run();
     }
}

Как я могу переопределить определение пула потоков tomcat и заставить его использовать мой класс? Есть ли лучший подход к решению этой проблемы?


person Julias    schedule 20.05.2012    source источник
comment
Откуда берутся данные. Если все потоки имеют одинаковые данные, в чем смысл? Вы должны рассказать нам больше о своей конечной цели. Что вы ставите в треде локально?   -  person JB Nizet    schedule 20.05.2012
comment
Я уверен, что все возможно, но, вероятно, существует более простое решение. Не могли бы вы объяснить, какую проблему вы хотите решить?   -  person AlexR    schedule 20.05.2012
comment
Я хочу иметь сериализатор json в локальных потоках каждого потока, чтобы повысить производительность, а не создавать его для каждого запроса и не делать его одним централизованным объектом.   -  person Julias    schedule 20.05.2012
comment
Как вы определили, что существует проблема с производительностью?   -  person Pidster    schedule 24.05.2012


Ответы (2)


Для этого вам не нужно возиться с потоками Tomcat. Просто используйте следующий код:

public class JsonSerializerFactory {
    private static final ThreadLocal<JsonSerializer> JSON_SERIALIZER = 
        new ThreadLocal<JsonSerializer>() {
            @Override 
            protected JsonSerializer initialValue() {
                 return new JsonSerializer();
            }
        };

    public static JsonSerializer get() {
        return JSON_SERIALIZER;
    }
}

Каждый раз, когда вам нужен сериализатор, вызывайте JsonSerializerFactory.get(), и он вернет локальный экземпляр потока и лениво создаст его, если он еще не существует.

person JB Nizet    schedule 20.05.2012
comment
Не создает ли это утечку памяти, если приложение повторно развертывается? То есть когда эти JsonSerializers будут удалены? - person meriton; 20.05.2012
comment
Очень хороший ответ, спасибо. О повторном развертывании - уничтожаются ли текущие потоки при повторном развертывании? - person Julias; 20.05.2012
comment
Это зависит от версии tomcat. См. wiki.apache.org/tomcat/MemoryLeakProtection#customThreadLocal. - person JB Nizet; 20.05.2012
comment
Отличный пример того, почему Tomcat пришлось добавить защиту от утечек ThreadLocal. Это не хороший код. - person Pidster; 24.05.2012
comment
Тот факт, что Tomcat не мог правильно работать с таким нормальным и простым кодом в предыдущих версиях, не делает его плохим кодом. Код приложения не должен иметь дело с проблемами повторного развертывания. Это роль сервера приложений. Вот как предполагается использовать ThreadLocal. - person JB Nizet; 25.05.2012

Tomcat Executor построен на основе классов java.util.concurrent, поэтому вы можете заменить классы компонентов Tomcat, но я не думаю, что это хорошая идея.

Если вам нужно поместить данные в область запроса, есть несколько хорошо определенных способов сделать это в Спецификации сервлета, например, ServletRequestListener. Вы также можете использовать фильтр сервлетов и выборочно добавлять его только к тем запросам, которые в нем нуждаются.

person Pidster    schedule 24.05.2012