File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes JSP and the fly likes Can I Kick off Thread in JSP That Runs Even When JSP Returns? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » JSP
Bookmark "Can I Kick off Thread in JSP That Runs Even When JSP Returns?" Watch "Can I Kick off Thread in JSP That Runs Even When JSP Returns?" New topic
Author

Can I Kick off Thread in JSP That Runs Even When JSP Returns?

Robert Paris
Ranch Hand

Joined: Jul 28, 2002
Posts: 585
I have a task that takes a little bit of time, longer than I can wait in a JSP (or rather, longer than the user can wait). However, I need to do this task. Is there a way to kick this off into another thread (or something else) that will continue to run even if the JSP page returns to the user?
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
In general it's bad practice to kick off threads in a JSP/servlet context. All sorts of hard-to-track-down things can go wrong.
If you need this sort of asynchronous processing, why not consider JMS (Java Messaging System)?


Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
Michael Bronshteyn
Ranch Hand

Joined: Mar 26, 2002
Posts: 85
You can use jspInit() method to create an object which either extends Thread or implements Runnable. You can start thread at jspInit, or at the request time.
It may result in some java code inside Jsp. Thus I'd rather use JavaBean to hold multithreaded object and check bean properties instead.


Michael
SCJP2
Robert Paris
Ranch Hand

Joined: Jul 28, 2002
Posts: 585
Thanks for the replies.
With regard to JMS:
Alot of different users will be using my app for their JSPs and they're not all the most skilled. The more Java things they need to configure, install, run, the worse the situation and the less useful my program becomes.
It is totally fine if there's no feedback for the JSP page as to whether my thing ran - I don't care about that. So given that those concerns are not a problem here, Frank: is it possible to do what I asked? Can I kick off a thread that does what I want and even if the JSP page finishes in 1 second, and the task takes 14 seconds, it will continue to run and the page will already be returned to the web browser. Is this possible? Is it something other than a thread?
For Michael:
Yes, but if I do that, will that Thread continue to run and NOT hold up the JSP page completing and returning the HTML to the web browser?
Robert Paris
Ranch Hand

Joined: Jul 28, 2002
Posts: 585
I think this is the answer!! When I do this in a JSP, the page returns instantly, and my thread continues running.
http://www.mail-archive.com/jrun-talk@houseoffusion.com/msg06461.html
A few things I changed from that user's suggestions:
1. I do NOT save it in Session.
Doesn't seem to matter, the thread continues runnning on its own (as evidenced by the page returning instantly but my System.out.println messages continuing to be printed)
2. Do not do any redirecting of the page.
Michael Bronshteyn
Ranch Hand

Joined: Mar 26, 2002
Posts: 85
there is one more thing to be aware. jsp page is compiled into servlet. you don't know how many instances of the servlet object servlet container is going to instanciate, thus if you save thread object into instance variable, you may find more than one object which started thread on background. having multithreaded object initialized into static member can be a safer solution.
Robert Paris
Ranch Hand

Joined: Jul 28, 2002
Posts: 585
Michael,
Thanks for the reply. Could you give some sample code for an idea of what you mean? I think I understand, but want to be sure. I ask mainly because i remember reading that static means something diff. in servlets than in regular java environments.
Michael Bronshteyn
Ranch Hand

Joined: Mar 26, 2002
Posts: 85
please find example 3-7 from "Java Servlet Programming" by Jason Hunter which I used when developed background processing thread for my project.
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class PrimeSearcher extends HttpServlet implements Runnable {
long lastprime = 0; // last prime found
Date lastprimeModified = new Date(); // when it was found
Thread searcher; // background search thread
public void init() throws ServletException {
searcher = new Thread(this);
searcher.setPriority(Thread.MIN_PRIORITY); // be a good citizen
searcher.start();
}
public void run() {
// QTTTBBBMMMTTTOOO
long candidate = 1000000000000001L; // one quadrillion and one
// Begin loop searching for primes
while (true) { // search forever
if (isPrime(candidate)) {
lastprime = candidate; // new prime
lastprimeModified = new Date(); // new "prime time"
}
candidate += 2; // evens aren't prime
// Between candidates take a 0.2 second break.
// Another way to be a good citizen with system resources.
try {
searcher.sleep(200);
}
catch (InterruptedException ignored) { }
}
}
private static boolean isPrime(long candidate) {
// Try dividing the number by all odd numbers between 3 and its sqrt
long sqrt = (long) Math.sqrt(candidate);
for (long i = 3; i <= sqrt; i += 2) {
if (candidate % i == 0) return false; // found a factor
}
// Wasn't evenly divisible, so it's prime
return true;
}
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
if (lastprime == 0) {
out.println("Still searching for first prime...");
}
else {
out.println("The last prime discovered was " + lastprime);
out.println(" at " + lastprimeModified);
}
}
public void destroy() {
searcher.stop();
}
}
this example does not have Thread object as static. most of the time servlet container will create one servlet object and share it between multiple threads.
but you can setup your web.xml to have more than one registered name ( but not URL pattern ) for servlet( ref. "Java Servlet Programming" by Jason Hunter page 40 ). in this case servlet container will create a new instance of the servlet object for each name.
if in the code above you make searcher member static and initialize it as singleton, you will make sure that for any number of instances you still have only one thread running on background.
note, when you create your background processing object you don't need to extend HttpServlet.
also, make sure you have code to stop your running background thread. even if your servlet instance is going to be destroyed, the thread is still going to be running on the background until virtual machine exits.
Pat Wallwork
Ranch Hand

Joined: Sep 23, 2001
Posts: 72
Robert,
I do this sometimes in my jsp pages as well...the easiest way I found was to do this in your jsp:

hth's,
-Pat
Robert Paris
Ranch Hand

Joined: Jul 28, 2002
Posts: 585
Michael,
Thanks again for the reply, but your post does everything except show me an example of doing a static variable correctly in JSP/Servlet! Lol. Do you have an example? And with your example, can you post what the scope of that variable would be, and in what ways it would constantly use the same instance? (Since you said it would be one thread - which I'm not sure I want)
Also, should my thread indicate in some way that it's done and ready to be disposed of?
Michael Bronshteyn
Ranch Hand

Joined: Mar 26, 2002
Posts: 85
example i used can not be used for static thread because it uses an instance of servlet class and it is not a good idea.
i don't have a code on hand which i can post to show you exact example, while i think you can figure it out.
i am not sure what you mean for scope of varialbe, but static members are shared between all instancess of the objects.
Bhupinder Dhillon
Ranch Hand

Joined: Oct 12, 2000
Posts: 124
Originally posted by Michael Bronshteyn:
you don't know how many instances of the servlet object servlet container is going to instanciate

Container is supposed to instantiate only one servlet object unless it's SingleThreadModel OR if you define multiple servlet definitions in web.xml with different init params. So you if you're sure it's not doing the latter then there should be only once instance in the container.
From servlet 2.2 specs:
3.2 Number of Instances
By default, there must be only one instance of a servlet class per servlet definition in a container.
In the case of a servlet that implements the SingleThreadModel interface, the servlet container
may instantiate multiple instances of that servlet so that it can handle a heavy request load while
still serializing requests to a single instance.
In the case where a servlet was deployed as part of an application that is marked in the deployment
descriptor as distributable, there is one instance of a servlet class per servlet definition per VM in a
container. If the servlet implements the SingleThreadModel interface as well as is part of a
distributable web application, the container may instantiate multiple instances of that servlet in
each VM of the container.
3.3.1 Loading and Instantiation
.....It is important to note that there can be more than one instance of a given Servlet class in the
servlet container. For example, this can occur where there was more than one servlet definition that
utilized a specific servlet class with different initialization parameters. This can also occur when a
servlet implements the SingleThreadModel interface and the container creates a pool of
servlet instances to use.
[ January 15, 2003: Message edited by: Bhupinder Dhillon ]
Michael Bronshteyn
Ranch Hand

Joined: Mar 26, 2002
Posts: 85
the point was that when you are writting servlet ( or jsp ) code you don't know if your servlet in web.xml is not going to be configured for more than one servlet name ( in this case servlet container will create another instance ). thus if you must have a singleton you should not assume that you will always have only one instance of servlet.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can I Kick off Thread in JSP That Runs Even When JSP Returns?