Reputation: 2109
I have code that schedules one-time tasks to execute and does this over and over. It looks something like this.
public static void main(String[] args)
{
while(true)
{
....
TimerTask closeTask = new CloseTask(cli);
Timer timer = new Timer(true);
timer.schedule(closeTask, (long) (iPeriod * 60 * 1000));
...
}
}
public class CloseTask extends TimerTask
{
Client client;
CloseTask(Client in_client)
{
client = in_client;
}
public void run()
{
try
{
for(int iRetries = 0; state == OPEN; iRetries++)
{
logger.log_trade_line_grablock( "Thread " + Thread.currentThread().getId() + ": About to send message", true, true, true, true, true);
client.send_mesg("close");
logger.log_trade_line_grablock( "Waiting 5 seconds before retrying ", true, true, true, true, true);
Thread.sleep(5000);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
The intent of the run()
method in the CloseTask
class is to loop until the state
variable changes from OPEN
state to something else. However, intermittently the timer threads simply disappear, while state
still equals OPEN
, which I know by printing out all the thread ID's of the currently running threads every 5 minutes.
So my questions:
1) The only explanation I can think of is that the CloseTask
object is throwing uncaught exceptions. Is that correct?
2) If 1) is correct why isn't my try catch block catching these exceptions?
3) If 1) is correct is there a way to catch these exception that slip through uncaught?
Thanks for any insight into this issue.
Upvotes: 2
Views: 983
Reputation: 40256
The boolean you are passing in tells whether or not the thread created will be daemon
. If it is daemon, the thread will be stopped once all non-daemon threads are finished. Since the only non-daemon thread being run in your application is the main thread then it will immediately be stopped after the main method is completed.
As Jon Skeet mentioned there is some completion operations done if no live thread is referencing the Timer and the tasks complete, but if it's daemon and the main method completes, it may not exit gracefully. To continue the documentation
... However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating. If a caller wants to terminate a timer's task execution thread rapidly, the caller should invoke the timer's cancel method.
To answer your question
The only explanation I can think of is that the CloseTask object is throwing uncaught exceptions. Is that correct?
If the JVM kills a non-daemon thread, it won't throw any exception. So you won't really know that it happened.
Upvotes: 1
Reputation: 1501043
You're creating a Timer
instance, but not making sure that it doesn't get garbage collected.
From the documentation:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection).
So basically, you need to hold on to the reference to the Timer
you created instead of just using a local variable.
Upvotes: 2