I have this simple code using util.Timer
public class CheckDBAccessListOpenAccesses extends TimerTask {
public static void main(String[] args) {
CheckDBAccessListOpenAccesses object = new CheckDBAccessListOpenAccesses();
}
private CheckDBAccessListOpenAccesses() {
System.out.println("Start");
Timer whatAccessAreOpen = new Timer();
whatAccessAreOpen.scheduleAtFixedRate(this, TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));
Thread.sleep(100*60*1000);
System.out.println("finish");
}
#Override
public void run() {
System.out.println("one minute");
}
}
When I run the code, the process runs forever.
I want the process to stop when the main Thread ends. Why is the Timer keeps the process alive? is there a way to prevent it?
Java has two types of Threads: user threads and daemon threads. User threads prevent the JVM from terminating, daemon threads do not. By default, a Timer is backed by a user thread, unless it is specified to run as a daemon in the constructor.
To prevent the Timer from keeping the process alive, instantiate the Timer with:
new Timer (true)
See: https://docs.oracle.com/javase/8/docs/api/java/util/Timer.html#Timer-boolean-
Well, that's in the Timer's API.
The Timer#scheduleAtFixedRate method:
Schedules the specified task for repeated fixed-rate execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.
[...]
You may want to use Timer#schedule for one-shot operations, instead.
Otherwise, and what you likely really want, is to have the Timer object visible from your main thread, so you can just invoke Timer#cancel on it when you wish to cancel the scheduled operation, e.g. when your main thread terminates.
Related
I have a Java program that I need to kill a thread.
It does not need to be killed gracefully, I just need the thread to end, as I am calling it to kill a bunch of threads as an action handler for JavaFX on window close.
Here is the program in question: https://github.com/Aashishkebab/Sorting-Simulator
Basically the program implements a bunch of sorting algorithms and allows the user to choose one, and then choose a block size.
The program splits the sorting into blocks of the size that the user inputs, and then sorts all of these concurrently on separate threads.
However, closing the window causes the threads to keep sorting in the background. I need to be able to cause all of these operations to stop on window close (or pressing a kill button or whatever the case).
I am not worried about the safety of the data, or if null pointers occur, etc. I just want the program to truly exit.
Just make the threads daemon threads. A daemon thread is one which does not prevent the JVM from exiting. This can be as simple as
Runnable mySortAlgorithm = ... ;
Thread thread = new Thread(mySortAlgorithm);
thread.setDaemon(true);
thread.start();
If you are using an executor to manage your threads, i.e. you have
Executor exec = ... ;
//...
Runnable mySortAlgorithm = ... ;
exec.execute(mySortAlgorithm);
you can create an executor that creates daemon threads, for example
Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
//...
Runnable mySortAlgorithm = ... ;
exec.execute(mySortAlgorithm);
If you use Executors to create an ExecutorService and submit() your Callable tasks to that, all task threads can be stopped with myExecutorService.shutdownNow()
If you want even better control over your threads, look into CompletableFuture.supplyAsync()
What about System.exit(myExitCode);.
But a cleaner solution would be to make your sorting algorithm cancellable. See here for example.
Also useful is this.
It's not safe kill thread directly.
Recomended way is to use a flag that can notify to thread that is time to stop.
If you can access and modify code you can create a method named stop() in your thread class so when you need to kill process you can call myClass.stop().
For example:
public class myClass{
private boolean keepAlive = true;
public void run(){
keepAlive = true;
while(keepAlive){
//do work
}
}
public void stop(){
keepAlive = false;
}
}
I did some reading of other post but didn't find an exact answer to what I'm looking for, so I hope someone can give some some clarification.
I have a program that will run for some time. I have some threads that run in the back ground that perform various tasks, to keep things simple let think of 3 threads. ThreadA performs a task every 10 seconds, where ThreadB does something every 30 seconds and ThreadC does something every 5 mintues.
I don't use busy waiting, and put the threads to sleep for the designated times.
My question is regarding a clean shut down. I have a variable that each of the threads have read access too, so they can see when the user initiates the exit of the program. The next time the threads are active, they exit their loops and join and all is good. But you can see that ThreadC only wakes up every 5 minutes.
The question I have is can I signal the sleeping threads to wake up and exit before their sleep time is over? If this is not possible, do I need to rework the code to use wait() and notify() or is there a better way?
Thread.sleep throws InterruptedException if the thread is interrupted during the sleep. Catch that, and check your flag.
If the threads are sleeping with Thread.sleep(...), you can wake them up with Thread.interrupt(). Make sure you're handling the InterruptedException and testing Thread.currentThread().isInterrupted() in your loops.
You can call the interrupt() method on your thread and will make your Thread go to running state from block state, but it will throw an exception which is InterruptedException which by then you can shutdown your thread in the catch block
Also other solution is that you can use the Timer Task that will call the run method on a certain time you specified without putting your Thread to the block state
example:
public class TimerBomb {
Toolkit toolkit;
Timer timer;
int count = 0;
public TimerBomb(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(), seconds * 1000, seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
//do stuff here
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
new TimerBomb(5);
}
});
t.start();
System.out.println("Task scheduled.");
}
}
It will run every 5 second forever.
You should look into ExecutorService and its shutdownNow() method (which generally interrupts all the active threads). You sense reinventing the scheduling wheel.
All of the other answers are good answers to the question that you actually asked, but none of them gives the best answer to the question that you should have asked. The question is, what's the best way to schedule several periodic tasks that must recur with different periods? The answer is, use a java.util.concurrent.ScheduledExecutorService.
Like all ExeuctorServices, it provides methods, shutdown() and shutdownNow(), for when you want the tasks to stop.
The articles on the site related to Timer talk about how to use Timer to program.
I ask a different question.
How does Java perform Timer method?
Since it is said to avoid time-consuming work by not to use while loop to check whether the current time is the required time point, I think Timer is not implemented simply by using while loop to continuously checking and comparing the current time to the desired time point.
Thank you!
I think Timer is not implemented simply by using while loop to continuously
checking and comparing the current time to the desired time point.
YES, IT IS. The only optimization is; it is using priority queue based on nextExecutionTime for tasks.
JavaDoc states
Timer object is a single background thread that is used to
execute all of the timer's tasks, sequentially. Timer tasks should
complete quickly. If a timer task takes excessive time to complete,
it "hogs" the timer's task execution thread. This can, in turn, delay
the execution of subsequent tasks
Timer class contains
TaskQueue which is a priority queue of TimerTasks, ordered on nextExecutionTime.
TimerThread(queue) the timer's task execution thread, which waits (queue.wait()) for tasks on the timer queue.
TimerThread has private void mainLoop() { where continuous while(true) will keep checking the tasks by comparing nextExecutionTime with currentTimeMillis
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {
and if it reaches then calling
if (taskFired) // Task fired; run it, holding no locks
task.run();
According for the javadoc
This class does not offer real-time guarantees: it schedules tasks
using the Object.wait(long) method.
If you look in the code you will find a method called main loop. The first couple of lines are copied below.
private void mainLoop() {
while (true) {
try {
And... it uses a while loop inside of it along with Object.wait() to do the waiting.
I want to have a class that changes its own private variables every 2 seconds. I know that if I do something like
import java.util.Timer;
//...
Timer timer;
//...
timer.schedule(new ChangeSomething(), 2000);
It will execute ChangeSomething() after 2 seconds, is there a way to tell it to do something every 2 seconds, or, If I put inside ChangeSomething()
timer.schedule(new ChangeSomething(), 2000);
will it work?
On a side-note, what does timer.cancel() exactly do?
Use timer.scheduleAtFixedRate() to schedule it to recur every two seconds:
Schedules the specified task for repeated fixed-rate execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.
From the javadoc for Timer.cancel():
Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it.
EDIT:
Relating to internal execution thread for a Timer that executes a single task once:
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). 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.
You will need to call to a different scheduling method of Timer, called scheduleAtFixedRate(...) which can get 3 parameters. The first 2 are identical to those of schedule you've used, while The third parameter indicates a period time in milliseconds between successive task executions.
import java.util.Timer;
//...
Timer timer;
//...
timer.scheduleAtFixedRate(new ChangeSomething(), 2000, 2000);
You can check the java pai doc for this method here: http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long)
Here is an example
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test extends TimerTask {
private int age;
public Test() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(this, new Date(), 2000);
}
/**
* Implements TimerTask's abstract run method.
*/
public void run(){
//toy implementation
System.out.print("Changing Data ... before change age is "+age+" ");
changeAge();
System.out.println("after change age is "+age);
}
private void changeAge() {
age = (int)Math.round(Math.random()*1000);
}
public static void main(String[] args) {
new Test();
}
}
To be more precise here: ChangeSomething() is the constructor of your ChangeSomething class. The constructor will be executed immediately when you pass the ChangeSomething instace object to the timer, not after 2 seconds. It's that object's run() method will be triggered after 2 seconds.
To execute that run() method repeatedly all 2 seconds, use schedule(TimerTask task, long delay, long period)
I tried everything. This one too How to stop the task scheduled in Java.util.Timer class
I have one task that implements java.util.TimerTask
I call that task in 2 ways:
I schedule Timer like this:
timer.schedule(timerTask, 60 * 1000);
sometimes I need that work to start immediately and it has to cancel timerTask if there is any that is working
cancelCurrentWork();
timer.schedule(timerTask, 0);
This implementation doesn't stop current work:
(documentation says: If the task is running when this call occurs, the task will run to completion, but will never run again)
But I need it to stop.
public static void cancelCurrentwork() {
if (timerTask!= null) {
timerTask.cancel();
}
}
This implementation just cancels the timer but leaves currently doing task to be finished.
public static void cancelCurrentwork() {
if (timer!= null) {
timer.cancel();
}
}
Is there a way in timer to STOP current executing taks, something like Thread.kill() or something? When I need that task to stop I want it to loose all its data.
There is no way for the Timer to stop the task in its tracks.
You will need to have a separate mechanism in the running task itself, that checks if it should keep running. You could for instance have an AtomicBoolean keepRunning variable which you set to false when you want the task to terminate.
if your timer is using some sort of file/socket etc, you can close that object from outside the timer, and the timer task will throw an exception, and you can use it to stop the timer.
but in general you need some sort of poison pill to successfully stop a separate thread/timer.