I've written the class VideoProcessor, which does some heavy processing on a video. If "started", a new Thread is created and the reference is saved in the field videoProcessingThread. The problem now is:
videoProcessingThread.interrupt();
This does not seem to have any effect, as isInterrupted() never evaluates to true. I also added other interrupt checks, just to be sure; but they don't "work" either. I've implemented a workaround:
videoProcessingThread.kill();
This seems to actually "kill" the thread. The method kill sets the boolean variable kill to true and that is evaluated correctly and the Thread returns.
videoProcessingThread = new Thread() {
boolean kill = false; // workaround
public void run() {
// init stuff
while (currentFrameIndex < totalFrames) {
if (isInterrupted()) {
System.out.println("isInterrupted");
return;
}
if (Thread.interrupted()) {
System.out.println("interrupted");
return;
}
if (Thread.currentThread().isInterrupted()) {
System.out.println("Thread.currentThread().isInterrupted()");
return;
}
if (kill) {
System.out.println("killed");
return;
}
}
// heavy processing
}
public void kill() {
kill = true;
}
}
What am I doing wrong?
First of all, calling interrupt() may not actually set the interrupted status, please see here in javadocs the exact conditions, sometimes it will just throw an InterruptedException.
Second, actually calling the interrupted() method will also clear the interrupted status in addition to returning it, so the next call to isInterrupted() (which only returns the current status, but does not clear it) may not do what you expect.
Using a boolean variable is probably not a bad method to accomplish this. You can read this article which goes into some details to clarify what exactly happens when you try to interrupt a thread and how to do it more or less reliably.
Your kill is not guaranteed to work, unless its volatile.
A thread is only interrupted when an operation which checks this flag is called. Some NIO operations with throw an exception if you call interrupt()
Most of the time using interrupt() is the same as setting a volatile flag. i.e. your task needs to check it regularly. The only safe way to kill a thread is to run it in its own process.
If you have a thread which is an Actor (it only modifies thread local memory) you could consider using stop(). The main problem with it is you can leave memory the thread modified in an inconsistent state. If you isolate the memory for that thread and discard it if the thread is stopped this should work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With