Killing Thread without periodically checking alive status - java

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. :)

Related

Stopping/Interrupting a thread after time limit

I have an application which uses a third party jar to do some task. My application uses Spring Executor pool to spawn the threads.
Question:
I need to stop the current execution of a thread if the executing time exceeds the time limit
What I did:
I googled a lot about interrupting thread. Most of says to check the interrupt flag whether the thread is interrupted or not and if interrupted throw an interrupted exception. But in thread I'm calling a method which is in a third party jar which do most of the stuffs so I can't go there and change the code for checking the interrupt flag.
Consider the following code snippet:
public void run() {
boolean isDone = false;
isDone = callThirdPartyMethod(); // here for some inputs thread takes more time (even never return for an hour!!) to process which I don't want and I need to stop/interrupt the thread
}
Approaches I follow for stopping/interrupting it
I had wrote a TimerTask which checks for the thread which is
exceeding the time limit and call the interrupt() on them (but it
seems nothing happens as they continue their execution).
I changed the code of my TimerTask from interrupting it to calling
the stop() on thread. This works but it throws ThreadDeath error.
Also what I read in most of the blogs and even in stackoverflow is
that we should never call the stop method.
Question: I need to stop the current execution of a thread if the executing time exceeds the time limit
There is no easy answer here. Typically you create one thread to make the third party library call and one thread to watch the clock and kill the other thread when a timer expires.
You can call interrupt the third party library thread but as you mention there is no guarantee that callThirdPartyMethod() will listen for the interrupt. You can call stop() but this is deprecated for good reasons.
The only addition mechanism is to close something that the third party library is using. Maybe a socket or other connection could be closes out from under the library.
If there is not way to do it then thread.stop() is your only (unfortunate) alternative unless you can get at the source of the library.
Otherwise you are SOL unfortunately.

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.

java: Stop the Singleton thread

I have a class XYZ which extends Thread and it is also a singleton (Yes. My application needs that).
In the run method, I have something like this:
public void run() {
service.start();
}
The time it takes for service.start() is huge.
Also, my application will not always need the thread to be run but can't decide in advance so while launching the application I am starting this thread.
Now, when application doesn't need the thread, it gets completed very quickly and all I need to do is wait for thread to die.
I tried to use stop() method but came to know that it is deprecated.
See this article for alternatives to calling stop()
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
stop has been deprecated a long time ago and should not be used. Thread termination is a cooperative process in Java (i.e. the interrupted code must do something when asked to stop, not the interrupting code) - one way is to call thread.interrupt() on the thread you need to interrupt.
You then need to catch the generated interrupted exception in the running thread or check the interrupted status regularly. Once the running thread detects that is should stop what it's doing, you can then run any cleanup tasks as required and exit whatever you were doing.
Signal your thread to do it's cleanup stuff, which you said is fast anyway, then just do a Thread.join.
Your question is highly dependant on exactly what is going on in service.start(). If it's opening external resources, then naturally you can't just barge in and kill the thread without proper cleanup. The start procedure will need to be coded explicitly for interruptibility with proper cleanup.

Killing a thread in java android

I have an application where i need to call 3 methods in 3 seperate threads and kill them afterwards. According to the Javadoc i noticed that thread stop() and even destroy() has been deprecated. its like I start one thread after the other and then kill similarly one after the other. Is there a particular way to kill the threads because I cant use the deprecated methods
Any help much appreciated.
Thanks again
You don't kill threads. You call Thread.interrupt(), and then react to the interrupted status or InterruptedException within the thread that's being interrupted. Or, you use a volatile flag. See the official documentation for background and more info.
Even better, use a thread pool / executor instead of raw threads, as suggested in comments.
Terminating a rogue thread in a way that works every time everywhere is pretty much impossible.
If you can control the source code of the running threads, you must add a method with which you can stop the thread when you need to. Basically this method changes a boolean variable and the thread checks that value periodically to see whether or not it can continue.
public class MyTask implements Runnable {
// Set this to true when thread must stop.
private boolean mStopRequested = false;
public void run() {
while (mStopRequested == false) {
// ...
}
}
}
If you call a 3rd party libraries that do not provide such a method, then you are out of luck and have to resort to ugly kludges. Once I had to kill a long running 3rd party library call by deleting a file that was accessed by the library (it threw a FileNotFoundException and exited). And that only worked on Unix systems.
Your mileage will vary.
Use join method until the receiver finishes its execution and dies or the specified timeout expires, whatever happens first.
thread1.join(1);
thread2.join(2);
thread3.join(3);
You must handle the exception.

Stopping and Restarting a Thread

I am trying to stop a current thread, change the run() method, and then restart that thread. I've looked around, and most of the methods are deprecated. However, interrupt() is not. I'm not sure if that's all you need to do.
interrupt();
start();
Would that work for what I needed it to do? It says that you should never start a thread more than once, and I don't know if it means
start();
start();
Rather than what I wanted to do.
Any help is appreciated.
Thanks
No, you can't do that. Fron the java online docs:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Don't restart a thread. You ALWAYS can rewrite your buisness logic to do this some other way. Consider using SingleThreadExecutor
In this case, you should create a Runnable object and pass it to a thread. Then you're creating different threads, but re-using the 'work' object.
Once you've started a thread, you can only interrupt it. Once you've done that, you can't start it again. See here for more details.
I'm not quite sure what you want to do, but it sounds like you have different Runnables that you want to run in sequence. In this case use a SingleThreadExecutor and submit your Runnables. It will run these in order, and so interrupting the first (successfully) will invoke the second.
I'm still not sure this is a good idea (it just doesn't sound right) and perhaps posting a more detailed problem description will give people a better idea of what you're really trying to do.
You should look into the basics of threading more. A thread can only run once. If you want to have the thread run different code, you need to create a new thread.
The interrupt() method will not stop a thread immediately (there is no supported) way to do that, it will stop only at certain points by throwing an InterruptedException().
I think you're approaching your problem in the wrong way. You cannot 'change the run() method of a Thread'. However what you probably want is to stop the previous thread and create a new one with a different run() method.
One thing to keep in mind however, is that Threads are designed to be as autonomous as possible and they don't like interference from other threads, which is why suspend() and resume() are deprecated. They create all sorts of bad behaviour depending on the circumstances and also prone to deadlocks.
You have 2 perfectly safe alternatives however:
Use wait() and notify() on a specific shared object.
Use sleep() and interrupt()
You need to decide within the run() method where it is safe to 'stop' the thread, and at that point put a wait() or sleep(). Your thread will only stop at that point.
The other thread can then do a notify() or sleep() so that the running thread is notified or interrupted. In case of interrupt() you will get an InterruptedException which you can use to terminate what you were doing in that thread.
After interrupting the old thread you can start a new thread initialised with a new Runnable implementation which has the different run() method.
Calling interrupt() will set the thread's interrupt status potentially interrupting blocking methods. This is part of a cooperative cancellation mechanism. You can't use it to force the thread to stop running.
Stopping threads has been deprecated for a reason: it is inherently dangerous as it may leave the state variables which it is manipulating in an inconsistent state.
You should not do this. Make your code from the run() method into a Runnable and submit it for execution to an Executor. This will return you a Future which you can use to retrieve its results as well as to cancel it.
If you want to reuse the same thread for other computations, use a thread pool, see for example Executors.newFixedThreadPool() and other factory methods in Executors.

Categories

Resources