Java: Thread/task expiration after specified milliseconds - java

In Java is there a sane way to have a thread/task run continuously and then end after a specified run time (preferably without using several timers)?
For instance, if I have a TimerTask, there doesn't seem to be a way to schedule that task to end after a certain number of milliseconds or at a specific time with the Timer class.
Sure, I can schedule a task to repeat after a number of milliseconds, but what if I want it to end after one iteration? I have to run another timer within this scheduled task? I'm hoping for a more elegant answer than that.
The answer provided in this question could work, but it is definitely not what I had in mind.
Essentially, I'm looking for something similar to the AutoReset property on C#'s System.Timers.Timer class

You can use an ExecutorService, grab the Future you get and .cancel() it after the time you want:
final Future<Whatever> f = executor.submit(...);
TimeUnit.SECONDS.sleep(xxx);
f.cancel(true);
Or you can have two services: one which executes, another which uses a ScheduledExecutorService for the cancellation.
NOTE: TimerTask depends on the system time, use a ScheduledExecutorService instead.

Simply create another thread and have it time it for when it wants the other thread to stop:
class ThreadTimer implements Runnable {
public void run()
{
Thread.sleep(3000);
MainThread.stopThread();
}
}
class MainThread implements Runnable {
public boolean running = true;
public void run()
{
// thread running code
if(!running)
return;
}
public static void stopThread()
{
running = false;
}
}
Where 3000 is the amount of time in milliseconds from when you want the thread to stop.
Since Thread.stop() is deprecated in Java, the next best way is to only execute the thread if a boolean is set to true. When you call to stop the thread, you're setting that boolean to false, making the code in the thread not run.
Because the void run() doesn't repeat itself and only executes once, if you set the boolean to false, it simply returns run() and halts the thread's execution.

If your task is running in a loop, you can check the current time on each iteration, and terminate the loop if enough time has passed.
Or, if your task involves sleeps, you can set a timer on another thread to call Thread.interrupt on the task.
The only other option would be to set a timer on another thread to call Thread.stop. However, Thread.stop has been deprecated, and there's no safe way to stop a general thread in Java.

Related

Terminate Runnable

I have a task executor which takes runnable as a task. I am starting a timer before calling runnable.run() method and stopping it when the runnable finished. I want to terminate the execution of run() method from the executor itself if the timer exceeds the time limit. I do not know what user will implement in run().
TaskExecutor.add(new Runnable () {
#Override
public void run() {
System.out.println("This is test job");
}}
);
This is how the user adds a new task. Every task runs in the same thread.
Edit
This task executor will act as a service to users. And because creating threads are expensive operation and requires native OS calls, I am trying to avoid them. Otherwise I would call Thread.interrupt() at some point. But I just want to know if there is a way to terminate the run() method from a parent object. Terminate means to stop something abruptly. As how we terminate processes in OS task manager.
How tasks are executed
while (jobQueue.isEmpty()) {
for (Job job : jobQueue) {
long startTime = System.currentTimeMillis();
job.run();
//There is a separate thread which checks
//for timeout flags by comparing the startTime
//with the current time. But all tasks are
//executed in the same thread sequentially. I
//only want to terminate single jobs that are
//timed out.
}
}
you can check condition for your timer,if timer exceeds you can interrupt your thread like-
Thread.currentThread().interrupt();
It will stop your current Thread.
I just want to know if there is a way to terminate the run() method from a parent object.
You can't really terminate a method, and you can't really do anything from an object.
It's often convenient to say "this object does X," or "this method does Y," but objects and methods don't really do anything. When you're talking about multi-threaded code, it's important to realize that everything your program does is done by threads. Methods are just the instructions that tell threads what to do, and objects are what the threads do it to.
You can interrupt a thread, which is only a good idea if the thread is designed to gracefully handle the interrupt; and you can terminate a thread, which basically is never a good idea.
Threads should always cooperate with one another. You need to provide a means by which your program can politely ask the client-provided callback to abort its work and return early. If the client code does not respect your request (i.e., if the client code does not cooperate), that's the client programmer's fault for not obeying your guidelines.
The simplest way to do it would be to simply expose some static boolean method that the client can periodically check to see whether it's time to abort.

how to repeat a task till certain time or till an answer has been received?

I want my ui thread to run an ansycTask (e.g. getting current Location)
However i want to limit it by time .how would you suggest doing this?
I have thought triggering a timer, but i'm not sure how.
in addition if i wanted to repeat an asyncTask that returns boolean value
and i want to give it 3 times retry chance.
how can i implement this?
I have thought about doing a few post with checking a static flag indicating an answer was received already, but i'm not sure this is the right way.
One way to ScheduledThreadPoolExecutor. This will allow you to run a thread at scheduled times. You can use methods scheduleWithFixedDelay to run your task at specified time.
Create your task by implementing Runnable. Use the Executor method scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit)
The executore will execute your task after the time you have specified. In your task, you can check for if the task is should retry or not. Once your conditions is satisfied or you have reached retries, you can cancel the task. You can use the shutdown method to end your task.
Simple class to accomplish this:
class RetryTask implements Runnable {
int retries = 3;
#Override
public void run() {
if(--retries == 0) {
//shutdown
}
if(location recieved) {
//shutdown
}
//else do your task
}
}

How do i run a method after a delay?

I have a question regarding calling methods after a certain amount of delay.
I want to call a Java method exampleFunction() after a delay of about 10 seconds. I have looked for solutions online and have come across the ScheduledThreadPoolExecutor(). So I have used this, but the thing is, once the function runs after 10 seconds, it doesn't exit from the thread. Is there any way I can exit from the thread? Or can I run the ScheduledThreadPoolExecutor() on the current thread instead of creating a new thread?
class Test {
...
exampleFunction();
...
public void exampleFunction() {
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.schedule(new Runnable() {
public void run() {
...do something here...
}
}, 10, TimeUnit.SECONDS);
}
}
So is there any way I can exit this thread after exampleFunction runs after a delay of 10 seconds? Or can I have the ScheduledThreadPoolExecutor use the current thread instead of creating a new one?
Or is there another way I can approach this problem? I want to be able to run exampleFunction() after 10 seconds on the current thread, instead of creating a new thread.
Edit: I think it may not be a thread issue. I'm still trying to figure out the problem is. Thanks everyone for your suggestions and advice.
EDIT: Can I pass an argument to exampleFunction() and then use it inside public void run()?
I believe your problem may be that you are not shutting down the executor after your submit the job to it.
exec.schedule(...);
exec.shutdown();
The jobs that have been submitted will continue to run but you have to shutdown the service after you've submitted the last job to it.
Based on all the comments and confusion, any answer is just a guess.
What I think you want:
The UI thread to invoke exampleFunction
'exampleFunction` to schedule a task for 10 seconds later and return immediately
In 10 seconds time, to have the run method be invoked on the UI thread
In Swing, this is done by using SwingUtilities.invokeLater.
ExampleFunction would look like this:
public void exampleFunction() {
new Thread() {
public void run() {
TimeUnit.SECONDS.sleep(10); //Will need a try/catch
SwingUtilities.invokeLater(new Runnable() {
public void run() {
...do something here...
}
});
}
}.start();
}
Note: SwingUtilities.invokeAndWait could also be used.
Note 2: Although not usually advised, a simple Thread here is simpler than making a new Thread pool.
Thread.sleep can be used if merely wishing to making the current thread block. If you do use a pooled executor, make sure to use it as a pooled executor - not one per (new) thread. To "exit" from a thread, just let execution run out of run. If using Swing, use the EDT.

Java Timer Reusage

I'm currently trying to get a small brick-breaker game I made to effectively use some form of power-ups or bonuses. I have have it mostly implemented right now. However I have a problem. I use java.util.Timer to determine how long the power-up lasts. Most likely, that power-up is going to be chosen (by a random number generator) more than once. However, a Java Timer can only be used once, and after it's cancel() method is called, it's done. Right now, I set up the game to mark a power-up as used and to never use it again. Is there a way to get around this? Here's the method that is called when the LongPaddle power-up is chosen:
public void longPaddleTime(int seconds) { //longPaddle Timer Method - gets called when the longPaddle bonus is enabled; shuts off longPaddle after a set amount of time
timerLP.schedule(new TaskLP(), seconds*1000);
}
class TaskLP extends TimerTask { //The task to be run after the timer in longPaddleTime runs out
public void run() {
longPaddle=false; //Disable LongPaddle
bonusActive=false;
LPused=true; //Mark as used
timerLP.cancel(); //Terminate the timer thread
timerLP.purge();
}
}
You don't need to cancel() your timer - Timer.schedule(TimerTask, long delay) will only run the specified task once. You only need to cancel() a timer if you want to terminate everything it's doing.
For your case (scheduling a task once), there's no cleanup required in the Timer class. If you had a repeating task and you wanted to stop just that one task, you could call TimerTask.cancel() to prevent it from reoccuring, while still allowing the Timer to be reused for other purposes.
You don't have to cancel the timer in your TaskLP.
Create a Timer object that lives in Application scope and just schedule new TimerTasks as need arises.
BTW, although not officially deprecated, Timer functionality has been superseeded by ScheduledExecutorService. I suggest, if you start from scratch to use this framework.
Executors utility class has a few methods that simplify the construction of the ScheduledExecutorService.

How should I terminate a looped sub-thread in Java?

I need to do some clean up work when I am going to terminate a looped thread. Such as saving a buffer so I can continue later.
PseudoCode:
private class CalculatePI(Byte[] resume) implements Runnable{
public void Run(){
while(true){
resume=resumeCalculating(resume);
}
}
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume));
Thread.sleep(200);
//And now I want to kill calculator
So what's the best way implement this?
Use a flag: But the problem is what if resumeCalculating() takes (EDIT: a long time) forever to end?
Put an exception into calculator, how?
Can I use event listeners or something? I thought they were used for GUIs
Just stop it? And Class Thread includes some kind of deconstructor that will be called when the thread is terminated and I could do the processing there?
EDIT by Owner:
I know I can use a flag. But consider this:
public void Run(){
while(true){
resume=calculate_stepone(resume); //takes one minute
resume=calculate_steptwo(resume); //takes two minutes
resume=calculate_stepthree(resume); //takes three minutes
resume=calculate_steplast(resume); //takes four minutes
}
}
Is putting a if(flag) saveResultsAndExit(); between every line practical or pretty?
I just want to throw away the half-processed results, and save the previous results.
The proper way to stop a thread is to interrupt it.
If the task running in the thread is performing IO or is using sleep then it will receive the signal (InterruptedException at that point); else the task should regularly poll to see if its interrupted.
Lets adapt the original poster's psuedocode:
private class CalculatePI(Byte[] resume) implements Runnable{
public void Run(){
while(!Thread.interrupted()) { //###
resume=resumeCalculating(resume);
}
}
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume));
calculator.run(); //###
//...
//And now I want to kill calculator
calculator.interrupt(); //### sends the signal
//...
calculator.join(); //### actually waits for it to finish
Answer to 1.: You can process the abort flag in resumeCalculating() too.
It is probably best to use a flag, wait for a while for the thread to end, and if it hasn't (resumeCalculating hasn't returned) kill the thread manually. It is probably best not to involve too much thread based logic in resumeCalculating, it really depends on how it is implemented as to how easy it is to abort halfway through an operation.
Design your program so that resumeCalculating does NOT take forever to continue. Also, synchronize access to your flag.

Categories

Resources