3.5 Background Processing

Java Servlet Programming, 2nd Edition > 3. The Servlet Lifecycle > 3.5 Background Processing

 
< BACKCONTINUE >

3.5 Background Processing

Servlets can do more than simply persist between accesses. They can also execute between accesses. Any thread started by a servlet can continue executing even after the response has been sent. This ability proves most useful for long-running tasks whose incremental results should be made available to multiple clients. A background thread started in init( ) performs continuous work while request-handling threads display the current status with doGet( ). It's a similar technique to that used in animation applets, where one thread changes the picture and another paints the display.

Example 3-7 shows a servlet that searches for prime numbers above one quadrillion. It starts with such a large number to make the calculation slow enough to adequately demonstrate caching effects something we need for the next section. The algorithm it uses couldn't be simpler: it selects odd-numbered candidates and attempts to divide them by every odd integer between 3 and their square root. If none of the integers evenly divides the candidate, it is declared prime.[6]

[6] Why do we look only for factors below the square root? Because any factor above the square root would need to correspond to a factor below the square root. If there are no factors before the square root, we know there can be none above.

Example 3-7. On the Hunt for Primes
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();   } }

The searcher thread begins its search in the init( ) method. Its latest find is saved in lastprime, along with the time it was found in lastprimeModified. Each time a client accesses the servlet, the doGet( ) method reports the largest prime found so far and the time it was found. The searcher runs independently of client accesses; even if no one accesses the servlet it continues to find primes silently. If several clients access the servlet at the same time, they all see the same current status.

Notice that the destroy( ) method stops the searcher thread.[7] This is very important! If a servlet does not stop its background threads, they continue to run until the virtual machine exits. Even when a servlet is reloaded (either explicitly or because its class file changed), its threads won't be stopped. Instead, it's likely that the new servlet will create extra copies of the background threads.

[7] Stopping threads using the stop( ) method as shown here is deprecated in JDK 1.2 in favor of a safer flag-based system, where a thread must periodically examine a flag variable to determine when it should stop, at which point it can clean up and return from its run( ) method. See the JDK documentation for details.


Last updated on 3/20/2003
Java Servlet Programming, 2nd Edition, © 2001 O'Reilly

< BACKCONTINUE >


Java servlet programming
Java Servlet Programming (Java Series)
ISBN: 0596000405
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net