0

I have completed the following Java Servlet construction: [I believe the main idea is that of consumer-producer]

  1. A Java servlet that receives multiple http POST requests

  2. It puts all requests into a Queue [ConcurrentLinkedQueue]

  3. All requests in the Queue are processed by a single and independent thread (like an engine). This thread works independently of the servlets. There is a good reason for the separate thread, since I need data from several and different http requests to do the processing. The Queue waits until it has enough requests and then starts the processing.

Now I'm in the final step: Once e.g. http request No1 has been processed by the independent thread engine, I need to notify the specific servlet thread (e.g. No1) where it came from so that I can reply, i.e. send the response back to the corresponding client.

How do I solve this threading issue? How can the single thread engine notify the correct servlet thread each time? How should I code this?

kostaspap
  • 345
  • 4
  • 10

3 Answers3

2

I don't know where are these requirements coming from, but there are several other, much simpler approaches to this problem:

  • Use ExecutorService. Simply submit a task to the pool and block on returned Future object. Very simple and effective. Once your task is ready, Future.get() will return the result

  • With Servlet 3.0 you can put whole processing in asynchronous thread. This is much more scalable. Basically you are submitting a task and releasing HTTP thread immediately. The asynchronous thread does not only process items in that queue but also returning HTTP response via AsyncContext object.

If you really need to use a queue and a separate thread, have a look at Java locks and conditions. But that's much more low-level work.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
1

Use a SingleThreadExecutor. Have your servlet create Callable objects and submit them to the executor, and then call get() on the returned Future:

Callable<Foo> callable = new Callable<Foo>() {
    // TODO implement call();
};
Future<Foo> future = executor.submit(callable);
Foo result = future.get();
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
0

Is there a good reason why you have a queue in a separate thread to perform the work? If the servlet needs to wait for the result of the processing before it can return a response to the client then why don't you just perform the processing in the same thread and return the result synchronously?

If you really want to do things asynchronously you can use a Future object to check the completion status of the computation, and obtain its results.

codebox
  • 19,927
  • 9
  • 63
  • 81
  • Good comment. There is indeed a good reason for the separate thread, since I need data from several and different http requests to do the processing. The Queue waits until it has enough requests and then starts the processing. – kostaspap Jul 22 '12 at 13:45
  • 2
    @kostaspap: that's an extremely important statement you just made, please make it part of your question. – Tomasz Nurkiewicz Jul 22 '12 at 13:48