Why are Java Timer threads disappearing? - java

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.

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.

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.

Related

How does ScheduledExecutorService handles terminated threads?

Does ScheduledExecutorService take care of handling terminated thread and generates a new one?
In the example below if any one of my thread terminates due to Error, what happens to thread pool size?
While debugging, I could notice one of the threads created by this service got silently terminated without printing any log statement. On checking Thread dump, I could still see 32 threads were still there and none of them were blocked.
public class CacheManager
{
private static class CacheRefresher extends Thread
{
Cache cache;
public CacheRefresher(Cache cache)
{
this(cache);
}
#Override
public final void run()
{
try {
LOG.info("cache is getting refreshed for " + cache.type);
cache.refreshCache();
} catch (Exception e) {
String subject = "Cache refresh failed in BMW";
LOG.log(Level.WARN, subject + ". Exception thrown:", e);
}
}
}
public void refreshCaches(List<cache> caches)
{
ThreadFactory ourThreadFactory =
new NamedThreadFactory("CacheHandler", true);
ScheduledExecutorService scheduleService =
Executors.newScheduledThreadPool(32, ourThreadFactory);
initialDelay = 60;
for (Cache cache : caches) {
service.scheduleWithFixedDelay(new CacheRefresher(cache), initialDelay, 20, TimeUnit.SECONDS);
initialDelay += 2;
cacheContainers.add(cache);
}
}
}
Uncaught exceptions in scheduled tasks will not cause scheduler's threads to terminate. However, it will prevent the failing task from being re-scheduled. See the respective documentation for ScheduledThreadPoolExecutor.html#scheduleWithFixedDelay:
The sequence of task executions continues indefinitely until one of the following exceptional completions occur:
[...]
An execution of the task throws an exception. In this case calling get on the returned future will throw ExecutionException, holding the exception as its cause.
While the JavaDocs for Executors.newFixedThreadPool explicitly mention this:
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
there is no such strong guarantee about the Executors.newScheduledThreadPool.
It is possible that it behaves the same in this regard, but that is an implementation detail you should not need to care about. The Executor service will provide/create enough threads to perform the given tasks.
As found in Javadoc newScheduledThreadPool(int) there always will be the specified amount of threads. Even if a thread will shutdown, there will be started another one. But in the first place, threads within the ScheduledExecutorService should be reused, even when a exception occurs within the Runnable.run().
And sure the threads are not blocked but waiting for new action to do...

How can I stop/pause particular thread from ExecutorService?

I have spring scheduler method. And ExecutorService
#Scheduled(fixedRate = 5000)
public void startSchedule() throws IOException{
threadPool.submit(() -> {
if(.......)return;
try {
generate(reportTasck);
} catch (NurException | IOException e) {
e.printStackTrace();
}
});
}
Each 5 sec start my method and if a necessary condition - start new thread with my logic. How can I stop/pause particular thread?
I have button on veb page, and if I press it I need to stop my thread.
There is already quite some discussion on SO regarding the stopping of threads. For a variety of reasons you should not stop or kill a thread as e.g. noted here:
How do you kill a thread in Java?
In order to allow the thread to properly cleanup its resources it should be the thread's responsibility to terminate itself by e.g. periodically checking some condition using e.g. a shared variable or via the thread's interrupt flag. See this answer for more details:
How to stop a thread created by implementing runnable interface?

Checking if a Thread is sleeping always returns true

I currently have the following problem:
I have made a 'Cache Updater Thread', which checks for updates and then sleeps for some amount of time. I have also build a Button, which enables the user to check for updates manually. The Thread is built like this:
public static Thread cacheUpdater = new Thread(new Runnable() {
int milliSecondSleepTime = 10000;
public void run() {
try {
cacheUpdater.setPriority(Thread.MIN_PRIORITY);
//Infinite loop
while (!terminate) {
syncStatus.set(0);
//Check for updates with some methods, not important here.
syncStatus.set(1);
Thread.sleep(this.milliSecondSleepTime);
}
}
catch (InterruptedException e) {
//First check if it is termination time
if (!terminate) {
syncStatus.set(0);
this.run();
}
}
catch (Exception e) {
System.out.println(e);
}
return;
}
});
If the user clicks the manual-update button, the following code is being runned:
#FXML public void syncOnRequest() {
//Only call interrupt, because then it will start again when terminate is still false
CacheManager.cacheUpdater.interrupt();
System.out.println(CacheManager.cacheUpdater.getState().equals(State.TIMED_WAITING));
while (!CacheManager.cacheUpdater.getState().equals(State.TIMED_WAITING)) {
//LOOP FOREVER
}
//Some code that needs to be executed after the cache is updated
}
I would like to continue executing code in the syncOnRequest() method, when the cache updater is ready with its manual update. I had the idea to check if it is sleeping, but this is not working, because the System.out.println() immediately returns true. I have measured the time it takes to do the update, and its between 200 and 400 ms.
What am I doing wrong here? And why is it always returning true?
Additional question: sometimes a click on the button just kills the Thread, because it just woke up. The InterruptedException is not thrown.
How can I make sure the Thread will also restart in that case?
Note that Thread#interrupt() is the only polite way to ask your thread to interrupt itself (unless you explicitly implement another). Using it to restart the check is therefore a bad practice. So is checking the thread state for synchronization purposes and exposing the thread that keeps your cache up-to-date to external clients.
You manager should have a updateCache() method you will call directly from UI code and auto-update thread will call the same method periodically*. In that method, make sure that access to your cached data is either correctly synchronized or it happens atomically.
*) Instead of implementing your own periodic thread, consider using
Timer and TimerTask classes as well as making it a daemon thread.

Java - stopping all tasks in ExecutorService

I have a few executor services which schedule local tasks such as reading a file, connecting to db etc. These processes do huge amount of logging, which is extensive based on the fact there are many threads running concurrently, writing their own thing into the log.
Now, at some point in time an exception can be raised, which reaches the main method where all exceptions are caught. I am then shutting down all the services and cancelling each task, hoping to prevent all further messages to the log. Unfortunately, the messages are still showing up after I shut everything down... Any ideas?
UPDATE:
Here is some code
public class Scheduler{
private final ExecutorService service;
private final ConcurrentMap<Object, Future<V>> cache;
...
public void shutDown() {
service.shutdownNow();
for (Future task : cache.values())
task.cancel(true);
}
The task will carry on running until it reaches a point where it detects the Thread has been interrupted. This can happen when calling some System or Thread functions and you may get an exception thrown. In your case you probably need to check yourself by calling
Thread.currentThread().isInterrupted()
It is a good idea to do this if your code runs loops and you are expecting to be stopped in this way.
When you shutdownNow your executor or call cancel(true) (by the way shutdownNow already cancels the already submitted tasks so your loop is unnecessary) your tasks get interrupted.
Depending on how they react to the interruption, they might then:
stop what they are doing immediately
stop what they are doing after a while, because the interruption signal is not being checked regularly enough
continue doing what they are doing because the interruption signal has been ignored
For example, if your tasks run a while(true) loop, you can replace it with something like:
while(!Thread.currentThread().isInterrupted()) {
//your code here
}
cleanup();
//and exit
Another example:
for (int i = 0; i < aBigNumber; i++) {
if (Thread.currentThread().isInterrupted()) { break; }
//rest of the code for the loop
}
cleanup();
//and exit
Another example, if you call a method that throws InterruptedException:
try {
Thread.sleep(forever); //or some blocking IO or file reading...
} catch (InterruptedException e) {
cleanup();
Thread.currentThread.interrupt();
//and exit
}
Executors support 2 approaches of shutdown
shutdown() : Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
shutdownNow() : Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.
Ref : http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()
- Try using the shutdowNow() method, it will shutdown all the task started by this Executor throwing InterruptedException, but IO and Synchronized operation can't be interrupted.
Eg:
ExecutorService executor = Executors.newFixedThreadPool();
executor.execute();
...
...
executor.shutdownNow();
- cancel(true) method can be used with submit() method to shutdown a particular task.

Error in Thread Resuming after it is put to sleep

Hello i am having a problem with resuming a thread my code is
public boolean Wait(String Reply){
if (Reply.equalsIgnoreCase("Y")){
try {
t.resume();
}
catch (Exception e){
System.out.println("\n" + "The exception in resume thread method:::: " + e);
}
System.out.println("\n" + "In the Wait Function of Sender");
return true;
}
JOptionPane.showMessageDialog(j ,
"Please Wait While The User Accpets the Trasmission ",
"",
JOptionPane.INFORMATION_MESSAGE);
try{
t = new Thread(this);
t.sleep(100000);
}
catch (InterruptedException ie){
System.out.println(ie.getMessage());
}
return false;
}
I might explain you how it works as it will help u determine the problem.
First the thread is put to sleep......Then i call this public boolean Wait() function from another function named ReplyYes which passes the value "Y" and i then try to resume the thread but the t.resume() function call, instead of resuming the thread gives me a Java.Lang.Null.PointerException and the thread isn't resumed resulting in returning a FALSE value. Plus because of this thread i can't even Stop my Service i have to wait for the thread to timeOut.
Can anyone explain how to make it work correctly!!
Thank you
I think you misunderstand how Thread.sleep works. It is a static method.
The line t.sleep(100000); puts the current thread to sleep, not the thread t.
From the documentation:
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds
Emphasis mine.
You should start the thread and call sleep from that thread. See the following article for two different ways to start a thread:
Defining and Starting a Thread
Furthermore, resume is only for use with suspend and they have both been deprecated. From the documentation:
Deprecated. This method exists solely for use with suspend(), which has been deprecated because it is deadlock-prone. For more information, see Why Are Thread.stop, Thread.suspend,
Thread.resume and Runtime.runFinalizersOnExit Deprecated?
The reason you get a NullPointerException is probably because you try to create the new Thread object after you call t.resume(). So at that point, t still has the value null. Basically, your code needs to be completely rewritten from scratch. I would suggest following the tutorial I linked to above, then once you understand how to create threads move to the next chapters:
Pausing Execution with Sleep
Interrupts
at first you must start new Thread: t.start(); then try to wake up your thread: t.interrupt();
Call Thread.sleep() inside your run() method, this causes to sleep thread that calls this method

Categories

Resources