Asynchronous Processing = Spanning Threads = Valid?

Am I allowed (without any side effects) to create and run new Thread()

from a doGet() Method

servlet? Or is it somehow a resource leak?

Is it possible to pass an object " Session

" to a stream so that the result of my asynchronous processing (I am synchronizing correctly) in the session can later be stored? Or will this leak exist when using the "unrecorded streams" session?

=> What happens if the session expires in the meantime through the webcontainer as it has timed out and I access it from my thread? Or could this also lead to the side effect that keeping the session on a thread would prevent the webcontainer from not executing the session at all (and thus eventually leaking resources as sessions are not flushed)?

(I know there are other Solutions, like working with DB- (Job) Records, JMS, or Servlets 3.0), but I need to solve this problem as described by embracing a new stream in doGet.)

Many thanks! Jens

+2


a source to share


4 answers


First of all, what you want to do will LIKELY work. Depends on a whole bunch of things. But with a light load system, multiple requests, etc. It will probably work fine.

As for the problem of your session expiring, chances are "nothing will happen." You are happy to store and refer to information that no one else is looking at.

Naively, the server will end the session and remove the Session object from its internal map. In the meantime, your thread will link to it, and won't be wiser of whether it's good or not.

On a loaded server, the system can take user session information and serialize it to disk. When the user comes back, he will bring it back. In this case, you will be referring to the "old, orphan" session, which the user will not see again.



When your thread dies, the session will go along with the thread.

So, basically, if you have a single server instance that you are not a cluster, your server does not change sessions, that the server does not reboot (this is another point at which the server can save and restore sessions) and the session does not end - you should be good.

Yes, these are all restrictions on your technique, it doesn't make the wrong technique, it just limits the implementation. If your application and service can run normally within these limits, you are gold, and don't worry about it.

0


a source


It is considered bad practice to create a new thread from a servlet. A common alternative to introducing new threads is to use JMS / MDB for asynchronous processing.



0


a source


Although considered bad practice, it works for small projects. The best solution is to use an ExecutorService to get the job done (even if you are creating a singleton that contains the ExectorService). This approach should be compatible with the application thread pools provided by the application server (although I haven't tried it).

From your servlet, do something like:

Future future = myExecutorService.submit(new Task(workRequest));
session.put("result", future);

      

I would also not pass the user session object to the service, as the session implementation might include ThreadLocal. Instead, the executor creates a Future object that you can inject into the session. This way you can check if your asynchronous computation will complete later (or cancel or wait for it).

Future future = session.get("result");
boolean isDone = future.isDone();
boolean isCancelled = future.isCancelled();
showInJSP(isDone, isCancelled);

      

0


a source


Am I allowed (without any side effects) to create and start a new Thread () from the doGet () method of the servlet?

If it's well implemented, that's okay.

Is it possible to stream a "Session" object so that the result of my asynchronous processing (I am synchronizing correctly) in the session can be stored afterwards?

I wouldn't do that. Rather save Thread

in session. That way, you can always take it back for subsequent requests when needed.

What happens if the session in the meantime expires through the webcontainer, as it has timed out and I access it from my thread? Or could this also lead to the side effect that keeping the session on the thread would prevent the webcontainer from not executing the session at all (and thus eventually leaking resources as sessions are not flushed)?

The session will expire (and GC'ed if you don't keep a reference to it in yours Thread

), but the thread will keep running until it returns from the run()

method.A common practice is to check regularlyin the method run()

if the thread is interrupted or not (for example, once at every step or during every 1% progress). You can implement HttpSessionBindingListener

to signal an interrupt when the session has expired.

public class Task extends Thread implements HttpSessionBindingListener {

    public void run() {
        while (true) {
            someHeavyStuff();
            if (isInterrupted()) return;
        }
    }

    public void valueBound(HttpSessionBindingEvent event) {
        start(); // Will instantly be started when doing session.setAttribute("task", new Task());
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        interrupt(); // Will signal interrupt when session expires.
    }

}

      

0


a source







All Articles