[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1893
  • Last Modified:

Best way to create a thread from a servlet to do something other than handle requests

Hello:

My servlet handles standard HTTP requests.  In doing so, I understand that my web container, currently Tomcat, may decide to spawn more than one thread in order to handle the traffic.

I would like to create a thread, totally independent of handling requests, whose job is to read the database
every day, maybe once a day, and to take action on what it finds there.

How can I do this without getting in the way of the servlet container spawning its own threads for handling HTTP requests?

In what servlet method should I spawn the thread?  Can you please provide a complete code example?
I am not very experienced with threads and the different ways to create them.

Thanks,

Dan
0
danw11
Asked:
danw11
  • 4
  • 3
1 Solution
 
jmlonCommented:
From within a servlet you are free to create threads as you wish, same as in any Java application. When your thread finishes execution, it will be garbage collected as usual.

Here is a micro-example. Suppose DoWork is the class that does the work in another thread.

So from within your servlet you can create new threads to do the work asyncronously as illustrated in MyServlet class below.

Take into consideration:
- The thread must end quickly, otherwise you'll end up with lots of threads consuming your system resources.
- You should not pass the request and response objects to the thread. In particular you should try to output to the response output stream from within the thread.
- All the catches of multithreaded programming are against you. So if you intend to use any share data structure, be very careful in implementing the appropiated synchronized blocks.

public class DoWork implements Runnable {
  public void run() { ... }
}
 
public class MyServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {
      ...
      new Thread(new DoWork()).start();
      ...
   }
}

Open in new window

0
 
jmlonCommented:
Opps... sorry... he second consideration should read "You should not try to output to the response stream from the thread"
0
 
danw11Author Commented:
Actually, jmlon, my thread should not have anything to do with the servlet's request/response.

It's only constraint is that it must be running on the server side.  I also want only 1 thread created whose
job is to read from the database and send out emails based on what it finds.

So, perhaps it should run in its own separate java program.  I basically want it sleeping most of the time, with it waking up once per day, checking the database, sending out emails if applicable, and then going to sleep again.

Is there any benefit to have it spawned inside the servlet's init() method, so that it runs in the web container?  I do need to guarantee that only one of them get created.

Dan
0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
jmlonCommented:
The init method gets executed everytime you restart the Context. In particular as contexts may be restarted without shuting down tomcat (from the manager web-app), it is possible for the init method to be execute multiple times. This means that if you create threads in the init method, you will create a new one each time the context is restarted... so this approach should be handle carefully, for example keeping a static variable to indicate that a thread already exits.

Given the nature of your problem, another interesting alternative is using Quartz, a free library that lets you schedule tasks at given times and handles all the threading problem behind the curtain. If you want to check it out, this is the address:
http://www.opensymphony.com/quartz/
0
 
danw11Author Commented:
jmlon:

Looks like Quartz is just what I need.  Last question, is whether I can start it from the servlet init() method with the static variable to prevent it from being run again.  If Tomcat gets restarted, then it should be no big deal, since Quartz has persistence and knows about what events it has fired and what it has not.

If I can do this, then I won't have to restart the Quartz process, if the server goes down because it will simply get kicked off again when the init() method runs for the first time after a Tomcat restart.  Since I use Spring DAO for data access, I may be able to reuse that mechanism for data access as well.

Last thoughts?

Dan
0
 
jmlonCommented:
Oh... forgot to mention that. You have to add the "QuartzInitializer" as a servlet that is initialized on startup (in the web.xml) and it automatically creates the threads it needs and does all the house keeping for you. You don't need to worry about context or server restarts at all.

I have no experience with Spring, but when using hibernate for the persistence layer, it is perfectly OK to make use of it from within quartz tasks. So, I believe there should not be any problem with Spring either.


0
 
danw11Author Commented:
Excellent.  Quartz it is....I feel its a no brainer.
0

Featured Post

Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now