Java Servlet Threading

Я выполнил следующую конструкцию Java-сервлета: [Я считаю, что основная идея - идея потребителя-производителя]

  1. Java-сервлет, который получает несколько запросов HTTP POST

  2. Он помещает все запросы в очередь [ConcurrentLinkedQueue]

  3. Все запросы в очереди обрабатываются одним независимым потоком (например, механизмом). Этот поток работает независимо от сервлетов. Для отдельного потока есть веская причина, так как для обработки мне нужны данные из нескольких HTTP-запросов. Очередь ждет, пока у нее не будет достаточно запросов, и затем начинает обработку.

Теперь я на последнем этапе: как только, например, http-запрос № 1 был обработан независимым механизмом потоков, мне нужно уведомить конкретный поток сервлетов (например, № 1), откуда он пришел, чтобы я мог ответить, то есть отправить ответ обратно. соответствующему клиенту.

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

3 ответа

Решение

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

  • использование ExecutorService, Просто отправьте задачу в пул и заблокируйте возвращенную Future объект. Очень просто и эффективно. Как только ваша задача готова, Future.get() вернет результат

  • С Servlet 3.0 вы можете поместить всю обработку в асинхронный поток. Это гораздо более масштабируемо. По сути, вы отправляете задачу и немедленно освобождаете поток HTTP. Асинхронный поток не только обрабатывает элементы в этой очереди, но и возвращает HTTP-ответ через AsyncContext объект.

Если вам действительно нужно использовать очередь и отдельный поток, посмотрите на блокировки и условия Java. Но это гораздо более низкоуровневая работа.

Используйте SingleThreadExecutor. Пусть ваш сервлет создаст объекты Callable и отправит их исполнителю, а затем вызовет get() на возвращенное будущее:

Callable<Foo> callable = new Callable<Foo>() {
    // TODO implement call();
};
Future<Foo> future = executor.submit(callable);
Foo result = future.get();

Есть ли веская причина, по которой у вас есть очередь в отдельном потоке для выполнения работы? Если сервлету нужно дождаться результата обработки, прежде чем он сможет вернуть ответ клиенту, то почему бы вам просто не выполнить обработку в том же потоке и не вернуть результат синхронно?

Если вы действительно хотите сделать что-то асинхронно, вы можете использовать объект Future, чтобы проверить состояние завершения вычисления и получить его результаты.

Другие вопросы по тегам