Доступ к областям профилированных объектов в streamах
У меня есть веб-приложение, работающее в tomcat, где я использую ThreadPool (Java 5 ExecutorService), чтобы параллельно выполнять интенсивные операции ввода-вывода для повышения производительности. Я хотел бы, чтобы некоторые из компонентов, используемых в каждом объединенном streamе, были в области запроса, но streamи в ThreadPool не имеют доступа к контексту весны и получают прокси-отказ. Любые идеи о том, как сделать весенний контекст доступными для streamов ThreadPool для устранения сбоев прокси?
Я предполагаю, что должен быть способ зарегистрировать / отменить регистрацию каждого streamа в ThreadPool с весной для каждой задачи, но не успел найти, как это сделать.
Благодаря!
- Конфигурация нитей на основе №. процессорных ядер
- Пул streamов с использованием boost asio
- Когда использовать пул streamов в C #?
- Объединение streamов в C ++ 11
- В чем смысл гибкости streamов в ASP.Net?
- Как Threadpool повторно использует streamи и как это работает
- WaitAll для нескольких дескрипторов в streamе STA не поддерживается
- Именование streamов и streamов-streamов ExecutorService
- ExecutorService, как ждать завершения всех задач
- Как создать пул streamов, используя boost в C ++?
- Код для простого пула streamов в C #
- Параметры TaskCreationOptions.LongRunning и ThreadPool
- Создание пула streamов с использованием boost
Я использую следующий суперclass для своих задач, которые должны иметь доступ к области запроса. В основном вы можете просто расширить его и реализовать свою логику в методе onRun ().
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; /** * @author Eugene Kuleshov */ public abstract class RequestAwareRunnable implements Runnable { private final RequestAttributes requestAttributes; private Thread thread; public RequestAwareRunnable() { this.requestAttributes = RequestContextHolder.getRequestAttributes(); this.thread = Thread.currentThread(); } public void run() { try { RequestContextHolder.setRequestAttributes(requestAttributes); onRun(); } finally { if (Thread.currentThread() != thread) { RequestContextHolder.resetRequestAttributes(); } thread = null; } } protected abstract void onRun(); }
Я также хотел бы, чтобы у меня было 1000 голосов, чтобы дать принятый в настоящее время ответ. Я был в тупике, как это сделать в течение некоторого времени. На основе этого, вот мое решение, используя интерфейс Callable, если вы хотите использовать некоторые из новых вещей @Async в Spring 3.0.
public abstract class RequestContextAwareCallable implements Callable { private final RequestAttributes requestAttributes; private Thread thread; public RequestContextAwareCallable() { this.requestAttributes = RequestContextHolder.getRequestAttributes(); this.thread = Thread.currentThread(); } public V call() throws Exception { try { RequestContextHolder.setRequestAttributes(requestAttributes); return onCall(); } finally { if (Thread.currentThread() != thread) { RequestContextHolder.resetRequestAttributes(); } thread = null; } } public abstract V onCall() throws Exception; }
Не могли бы вы попробовать это наоборот? Используйте контейнер данных, который хранится в области запроса, и передайте его в пул streamов (возможно, поместите его в очередь, чтобы пул streamов мог принимать один контейнер данных за раз, работать над ним, отмечать его как «сделанный» и продолжать со следующим).
Spring имеет class ThreadPoolTaskExecutor, который вы можете использовать для управления пулом streamов из Spring. Тем не менее, похоже, что вам нужно будет сделать некоторую работу, чтобы сделать контекст Spring доступным для каждого streamа.
Я не уверен, что это сработает, даже если вы все-таки подключитесь к этому. Spring использует токен в локальном streamе для поиска объектов в области запроса (или сеанса), поэтому, если вы пытаетесь получить доступ к компоненту области запроса из другого streamа, вполне вероятно, что токена там не будет.