Stopping a recursive function in JAVA (from within a thread) - java

I think that this question has been brought up a few times in the past, but this is a little different and i could not find an appropriate answer anywhere.
I have a thread which calls (inside run()) another recursive function. This is actually a game engine and the recursive function is MiniMax.
The problem is, that when the user wants to Resign a game in the middle of the calculation, or even Undo a move, then how should I stop this function?
I cannot interrupt the thread with a boolean, since if the call to Minimax has already been made, then the program is inside this function and the thread will not check the interruption condition in order to termintate, calling interrupt() also does not work.
How do I stop such a function?

Calling Thread.interrupt() will throw InterruptedException at any wait() or sleep() that you call from the thread proccess, also remember to check isInterrupted() to "not do things".
When InterrupedException is thrown from sleep/wait (or join) the interrupted status is cleared, and a call for isInterruped() will return false, so remember to interrupt() the Thread after the Exception.
Also, using boolean interrupted() instead of isInterrupted() does clear interruped status, and a double check with interrupted may result in true following by false if not interrupted again between calls.
PS: One more suggestion, if interrupt is not enough, you can has a Queue that you can send messages and consume it from the running thread and interpret the value to stop the proccess (note that it's not a static flag, it's a Queue or something similar).

This solution is actually getting aroung the problem, not too elegant, but quite creative. I found it in the source code of junit's FailOnTimeout statement. What they do is to wrap a Callable in a FutureTask then launch it using a thread. Then they call FutureTask.get(long timeout, TimeUnit unit) which returns the result or throws a TimeoutException if timeout units passed and lets the thread run as long as it wants. I think the same idea could be used here as well.

Related

Understanding the usage of Thread.interrupt()

I am reading Interrupts from Oracle Docs. I am unable to figure out the following
part. It states that
What if a thread goes a long time without invoking a method that
throws InterruptedException? Then it must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received. For example:
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
I am scratching my head to understand, what does it mean by What if a thread goes a long
time without invoking a method that throws InterruptedException? Secondly, what is the usage
of Thread.interrupted(), it is a way, that thread can send a interrupt to itself? Whats the
practical usage of this scenario? Thanks.
This is a technique to keep the thread available for interruption.
Thread.interrupted() : checks whether present thread (itself) was interrupted by some other thread and clears the interrupted status flag. So it asks itself whether I was interrupted by someone to exit from what I was doing while I was performing a BIG BIG task and not listening to someone.
Imagine what would have happened if that thing was not done.
Suppose one iteration of heavyCrunch() takes 1 min worth of time. So n iterations will take n minutes.
Now suppose after starting the program you decide that you want to exit the program and terminate the program gracefully. So you interrupt the thread that is doing the heavy crunch.
BUT the thread is unknown of the fact that you have interrupted it as it is not checking for the interrupt status. So the program will not end until N Minutes have not completed and you will have to wait for long time.
So to gracefully terminate the thread, it should always keep checking the interrupt status to respond if someone else has requested interruption.
If you interrupt the thread running this code
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
}
it will only set interrupted status in the thread but it will not stop it
Thread.interrupted tests if interrupted status is set (and clears it) so by adding
if (Thread.interrupted()) {
return;
}
to the loop you make the code interruptible
Besides the fact that the phrase
What if a thread goes a long time without invoking a method that throws InterruptedException?
is deeply unclear, i suppose they mean the following:
Usually, if you have a thread that does some work in a while(true) loop, that is, a thread that does not terminate for a long time, you will probably place ANY function that throws InterruptedException in that thread (i.e. Thread.sleep(), a socket read, or anything!). This way, when your thread will be noticed an Interruption, one of those functions will catch it and you will be able to QUIT what you are doing in the thread (the thread does not just magically terminate itself).
Here comes what the phrase wanted to say:
WHAT IF YOU DO NOT WANT/HAVE to use these functions? Then you should use Thread.interrupted() to check whether you should QUIT doing what the thread is doing in the same way you would do if you catched an InterruptedException.
I hope this was clearer than the doc...
You can use interrupted() stop nicely any long running thread by intrrup thread somewhere and check the condition by Thread.interrupted() and based on this come out of run method.
Let say you one thread is blocked on some monitor and somewhere else that thread got interrupted which inturn will throw InterruptedExceptionand can come out of block state with interrupted status true.
I think interrupt is the best way to achieve stop long running task because an interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
May help you.
interrupt() sets from outside a flag in the object that can then be queried periodically by Interrupted() in the run() method.
I am scratching my head to understand, what does it mean by What if a thread goes a long time without invoking a method that throws InterruptedException?
A: If other thread call the interupt() method of this thread, and if this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. Otherwise, just set the interrupt status.
Secondly, what is the usage of Thread.interrupted(), it is a way, that thread can send an interrupt to itself? What's the practical usage of this scenario?
A: Thread.interrupted() is use to detect current thread's interrupt status, return true if it's set and then clear the status. You check this in order to respond to other thread's interrupt call, such as throw an InterruptedException and exit the thread or just exit.

Killing Thread without periodically checking alive status

I am runnning ExecutorService to perform a heavy computation, however I don't want to pollute the algorithmic class/method code with runner operations, in this case I'd like to do periodical check if it should be terminated gracefully.
I tried to search for solutions, still with no success, what I concluded is that this is not possible because only the thread itself is allowed to "autokill himself".
So my question is, if there is any way to terminate the thread "outside" of the thread by invoking some forcefull atempt to kill the thread.
If not maybe the best solution is to use aspect and intercept each iteration by adding a kill status check ?
You can call thread.interrupt(). This can cause thread to exit if it "respects" interruptions. For example if thread is blocked on IO or on wait() or on sleep() InterruptedExcption will be thrown. However if it is "blocked" on busy loop that does not check isInterrupted() flag interruption will not work.
Other way to indeed kill the thread is to call deprecated method stop(). However this is the last possibility. This method is deprecated because it indeed kills threads immediately (like kill -9) that can cause resource leaks.
Bottom line: to be able to stop threads grecefully you have to write code that is ready for this and the standard solution is to respect thread interrupts.
There sure is a way to forcefully terminate a thread: Thread#stop, but it is almost never advisable. Your idea with aspects seems quite fruitful, but if you have any sort of a main loop in your task, then consider replacing the loop with a series of submitted tasks where each task is one iteration. This will allow ExecutorService#shutdown to interrupt the processing. All state can be carried along in the instance of Runnable that is being submitted.
I haven't used the ExecutorService much. But reading the JavaDocs it appears that you submit a callable or runnable to the service. Those methods return a Future object which have a cancel method on it.
cancel(boolean mayInterruptIfRunning)
Have you tried using that?
The method thread.interrupt() stop the thread and you can call it outside the thread itself!
If you do not want to change the original implementation, you could wrap the thread. I'm not very familar with Java, so I'm sorry for the obviously not compiling example:
class ThreadWrapper extends Thread {
public ThreadWrapper(Thread t, TerminateCallback c) {
// ...
}
#Override
public void run() {
t.start(Thread.SYNCHRONOUS);
c.done(this);
}
}
You'd need to implement TerminateCallback yourself. I also assume there is a way to start a thread synchronously, Thread.SYNCHRONOUS is just a place holder. If this condition is fulfilled, I'm sure you can transfer it into valid code. :)

Unable to Cleanly Stop my Thread

I have created a class which extends Thread.
This class has several methods defined, some of which use Process and IO streams to download files (sometimes taking several minutes).
I also have a JButton which I use to stop the thread, it has an ActionListener which currently performs a ClassName.this.stop(); and this works perfectly.
Within the 'public void run()' method, I execute some of these methods and start the thread.
My question is, how can I replace my deprecated Thread.stop() method with an interrupt(), and use it to cleanly stop the thread?
I have looked at some solutions, which recommend using a boolean flag to check whether the thread has been interrupted, but seeing that the run() method simply executes a series of methods, the loop does not evaluate until all the methods have finished executing, and even then, I get a 'InterrupedException' and then the loop starts again.
Another issue is that if a download is in progress, it could take minutes for the download to complete and for the next check to see if the Thread has been interrupted. I'd like everything to stop and for the object to 'delete itself and everything in it', which is what Thread.stop() is currently doing correctly.
Any ideas anyone?
Don't use extra boolean sentinel flags, rely fully on the interruption mechanism. In long-runnig tasks which don't spend time in interruptible blocking methods; you must handcode occasional checks of Thread.interrupted() and break out of the task if true. If your loop goes on after InterruptedException, then fix this behavior. This aspect is completely in your hands. Don't ignore the exception; react by curtailing the work and ending the method.

How exactly does Thread.interrupt() and Thread.interrupted() work? [duplicate]

This question already has answers here:
What does java.lang.Thread.interrupt() do?
(10 answers)
Closed 9 years ago.
I am not clear regarding these two methods from the perspective of setting the status of the thread.
Java Docs say that Thread.interrupt() sets the threads interrupt status flag and calling the Thread.interrupted() method gives the status of the thread and clears the flag.
When this comes to use in real scenarios..??
When some other thread calls Thread.interrupt() the method sets Thread's interrupt status flag (initially false) to true. If the Thread is in blocking method like Thread.sleep(), Thread.join() or Object.wait() it unblocks and throws an InterruptedException.
Thread.interrupted() is a static method which can be use to check the current value of interrupt status flag, true or false. It also clears the interrupt status , setting the flag to false. That is calling it twice in a row may likely return false the second time even if it returned true the first time (unless the thread were interrupted again, setting the interrupt status flag to true after the first call)
Note a third method Thread.isInterrupted() which can check the interrupt status without resetting.
Typical use cases:
Break exceptionally from a blocking operation
Determine if it is desired to continue a long sequence of instructions at some logical save/stop point
Determine if it is desired to continue a sequence of instructions prior to beginning a long running task
Stop executing an iterative process that would otherwise continue into perpetuity (while(true) is bad, while(!Thread.interrupted()) is better)
You can use Thread.interrupt() to tell a thread to stop. When that thread performs a some blocking operations or checks the flag it trigger it to throw an InterruptedException to either wake up the thread or stop it.
While the purpose of interrupt() is usually to stop a thread, it doesn't mean it will. The interrupt can be ignored for long periods of time or completely ignored. If it triggers an InterruptedException this can be caught and loggged (or ignored) rather than stopping the thread.
Note: For threads in an ExecutorService, interrupting a task interrupts the thread and the ExecutorService catches this by design and doesn't shutdown the thread.

What happens when you invoke a thread's interrupt()?

I need to know what happens
when it is sleeping?
when it is running i.e., it is executing the given task.
Thanks in advance.
Interrupting a thread is a state-safe way to cancel it, but the thread itself has to be coded to pay attention to interrupts. Long, blocking Java operations that throw InterruptedException will throw that exception if an .interrupt() occurs while that thread is executing.
The .interrupt() method sets the "interrupted" flag for that thread and interrupts any IO or sleep operations. It does nothing else, so it's up to your program to respond appropriately- and check its interrupt flag, via Thread.interrupted(), at regular intervals.
If a thread doesn't check for interruptions, it cannot safely be stopped. Thread.stop() is unsafe to use. So you use .interrupt() to stop a thread, but when writing multithreaded code, it is up to you to make sure that .interrupt() will do something sensible. This TechRepublic article is a pretty good tutorial.
Judging by your previous questions, I assume you are interested in Java's behavior.
In Java, an InterruptedException will be thrown if the thread is currently blocking. If the thread is not blocking, the exception will not be thrown.
For more information, look here:
JavaDocs
For .NET languages, a ThreadInterruptedException will be thrown if the thread is currently blocking. If the thread isn't blocking the exception will not be thrown until the thread blocks.
Please tag your question with the language you want an answer for.
One more important information worth sharing is that, there are two methods in Thread Class
isInterrupted() and interrupted(). Latter one being a static method. isInterrupted() method call does not alter the state of interrupted attribute of Thread class, whereas interrupted() static method call can will set the value of interrupted boolean value to false.

Categories

Resources