Java thread start () without join () or interrupt () in servlets
I have a servlet filter that carries some logic and produces output before the request is served by the primary page. I have a new need to send output a few seconds later than at the time of its creation (with a delay of ~ 10 s). Due to some bad design choices I made earlier, I am unable to move the position of the filter to get the result posted after.
I chose to create a stream and delay the message transmission there. I am not currently taking any explicit steps to stop this thread from executing. I'm not sure if everything is clearing up correctly. Should I use the join () or interrupt () functions or any other Thread methods to safely clean up afterwards?
So, in 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 unnecessary things like creating DB links etc. to make it 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
}
}
}
source to share
Your code must be accurate, the VM will clean up the thread after it finishes.
However, I would advise java.util.concurrent.ScheduledExecutorService
against using such raw streams, but instead use by creating with java.util.concurrent.Executors
. This is a nicer abstraction that has better control over thread distribution.
source to share
Yes, everything will be cleaned properly. The thread dies after the run () method finishes, and since you no longer have references to this thread object, it will be properly garbage collected.
Just make sure the "Thread t" object won't refer to anything. To verify this, you can use: (new topic (...)). start ();
source to share
The servlet specification explicitly states (Thread Safety section) that request and response objects are not guaranteed to be thread safe, and that if these objects are passed to other threads, then the application is responsible for ensuring that these objects are synchronized and accessed only within the method servlet services. In other words, you must .join () those threads.
source to share
I had to answer the same question myself :)
I can admit that the streams are indeed cleaned up after they finish. If you are not completely sure that spawned threads will ever die, you should monitor the process and see how many threads are currently running. If the number continues to rise, something is out of control.
On a Unix system, you can use a command ps
, but I'm rusty, so I asked google instead of reading the man page. One of the first hits on google was This is a script that lists threads for each process . The result looks like this
PID TID CLS RTPRIO STAT COMMAND WCHAN
....
16035 16047 TS - S (java)
16035 16050 TS - S (java)
16035 16054 TS - S (java)
16035 16057 TS - S (java)
16035 16058 TS - S (java)
16035 16059 TS - S (java)
16035 16060 TS - S (java)
....
And I just grep
output for the process id (pid) of the process that I want to look at, and counting the number of lines each corresponding to a thread. Like this:
morten@squeeze: ~$ sh /tmp/list_threads.sh | grep 16035 | wc -l
20
So, the program I'm currently looking at (PID 16035) has 20 threads.
It doesn't require knowledge jconsole
or any code changes. The last part is probably the most important part as I didn't write the program myself, so now I don't need to read and understand the program.
source to share