Java Servlet Threading
Я выполнил следующую конструкцию Java-сервлета: [Я считаю, что основная идея - идея потребителя-производителя]
Java-сервлет, который получает несколько запросов HTTP POST
Он помещает все запросы в очередь [ConcurrentLinkedQueue]
Все запросы в очереди обрабатываются одним независимым потоком (например, механизмом). Этот поток работает независимо от сервлетов. Для отдельного потока есть веская причина, так как для обработки мне нужны данные из нескольких 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, чтобы проверить состояние завершения вычисления и получить его результаты.