views:

378

answers:

3

I have a servlet filter that carries some logic and produces output before a request is served by it's primary page. I have a new need to send out the output a few seconds later than at the moment it is generated (with ~10s delay). Because of certain poor design choices made earlier I can't move the position of the filter just to have the output sent after.

I've chosen to spawn off a thread and delay transmission of the message in there. I'm currently not taking any explicit steps to halt execution of this thread. I'm not sure if everything is getting cleaned up properly though. Should I be using join() or interrupt() or any other Thread methods to clean up safely after this?

So within the main servlet code I have something like this...

Thread t = new Thread(new MessageSender(message, 10000));
t.start();
//Carry on.. la la la

While there are other fields in this class, I just stripped out a lot of the non-essential stuff like making DB connections etc to make the point clear.

private static class MessageSender implements Runnable {
    String message;
    int delay;

    public MessageSender(String message, int delay) {
        this.message = message;
        this.delay = delay;
    }

    public void run() {
        try {
            Thread.sleep(delay);
            System.out.println(new java.util.Date() + ": hello world");                
        } catch (InterruptedException e) {
            // Do blah
        } catch (Exception e) {
            // Do blah blah
        } finally {
            // Close connections and stuff
        }
    }
}
+1  A: 

Yes, everything will be properly cleaned up. Thread dies after finishing run() method and as you have no more references to that thread object - it will be properly garbage-collected.

Just be sure that "Thread t" object will not be referenced by anything. To be sure on that, you can use: (new Thread(...)).start();

Max
+3  A: 

Your code should be fine, the VM will clean up the thread once it completes.

However, I'd advise not using raw threads like that, but instead using a java.util.concurrent.ScheduledExecutorService, creating using java.util.concurrent.Executors. It's a nicer abstraction that would better control your thread allocation.

skaffman
+1  A: 

The servlet specification explicitly states (section "Thread safety") that request and response objects are not guaranteed to be thread-safe, and that if those objects are handed off to other threads, then the application is responsible for ensuring that these objects are synchronized and that they are accessed only within the scope of the servlet's service method. In other words, you must .join() those threads.

bkail