2

Well, I have a thread in my video converter which is responsible for transcoding the video. It is a user thread with setDaemon(false).

To stop it, I call the threadName.interrupt() method however, it does not stop. It continues on !
How do I stop it?
Here is how I try to stop it:

if(getExecutingTaskID() == taskID){
         int what = JOptionPane.showOptionDialog(frame, 
                    "Do you want to interrupt an executing task?", 
                    "Task already running", 
                    JOptionPane.YES_NO_OPTION, 
                    JOptionPane.QUESTION_MESSAGE, 
                    null, null, null);
         if(what == JOptionPane.YES_OPTION){
             if(getExecutingTaskID() == taskID){
                 converter.interrupt();
             }
             return true;
         }
        }
        return false;
    }
An SO User
  • 24,612
  • 35
  • 133
  • 221

3 Answers3

4

A thread can only be interrupted when it calls a method that throws InterruptedException or if it calls Thread.interrupted and is coded to respond to it. If you want to be able to break your thread at any time, you'll need to build that into the code itself. Oracle provides a tutorial. Basically, your options are to use methods that throw InterruptedExcetion like sleep or wait, to periodically call Thread.interrupted, or have your own stop variable that you check periodically.

No matter how you slice it, you have to implement the interrupt. Java just has some simple ways of getting the message to the thread.

There is a Thread.stop method, but this method is considered extremely dangerous. This stops the thread and immediately releases all locks, which may leave objects in an unusable state. Using it is generally just a bad idea.

(Sorry to the major revamp of the answer.)

jpmc26
  • 28,463
  • 14
  • 94
  • 146
  • I used your `interrupted()` method. Now the thread checks if the flag has been set and then stops :) Thanks – An SO User May 25 '13 at 06:47
  • If a thread does not respond to interruption, it won't respond to `Thread.stop` either. – assylias May 25 '13 at 06:52
  • @assylias The [documentation](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#stop%28%29) suggests otherwise, but if you tested and it doesn't work as documented, that's kind of disturbing. – jpmc26 May 25 '13 at 06:57
  • You can read section "*What if a thread doesn't respond to Thread.interrupt?*" on [this page](http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html) for example: *It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt, it wouldn't respond to Thread.stop either.* – assylias May 25 '13 at 06:59
  • I guess it is discouraged to use `stop()`. `interrupt()` sets the interrupted flag which can b e checked by `interrupted()` method. I used that as a checkpoint mechanism :) – An SO User May 25 '13 at 07:01
  • 1
    It is very discouraged to use `Thread.stop`. That's a big no-no. @assylias The next sentence says, "Such cases include deliberate denial-of-service attacks, and I/O operations for which thread.stop and thread.interrupt do not work properly." I think what it means is that if some piece of code is hanging and the thread never reaches an interrupt check, then `Thread.stop` won't work either. In other words, they're saying, "Use the interrupt. `Thread.stop` won't save you from hang ups, anyway." I would agree with anyone who believed the section is poorly worded. – jpmc26 May 25 '13 at 07:03
  • http://stackoverflow.com/questions/5244312/why-doesnt-thread-stop-work-in-situations-where-thread-interrupt-doesnt-work – assylias May 25 '13 at 08:23
3

Quoting from the Java Tutorials (emphasis mine):

"An interrupt is an indication to a thread that it should stop what it is doing..."
"It's up to the programmer to decide exactly how a thread responds to an interrupt..."
"For the interrupt mechanism to work correctly, the interrupted thread must support its own interruption..."

Essentially, you have to watch for the "Interrupted" flag from within the thread and terminate it "from inside" when you detect the flag has been set. There are several ways to check for and handle interruption (see the link above) - e.g. you could use Thread's interrupted() method.

I don't know the inner workings of your readers and converters, but this while-loop seems like a good canditate for implementing the check:

while (reader.readPacket() == null) { 
    // code the next packet
    ...
    // Check for interruption
    if (Thread.interrupted()) {
       // We've been interrupted: terminate
       return;
    }
}
gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • This is exactly what I did. I used the `interrupted()` to check if it should stop. If yes, stop :) – An SO User May 25 '13 at 07:13
  • I usually say "Always glad to help", but I guess in this case it is more like "Always glad to know I could have helped if you didn't figure it out yourself first" (or something like that) :D – gkalpak May 25 '13 at 07:17
  • In that case: "Always glad to know I could have helped if the accepted answer hadn't helped you figure it out yourself first" :D – gkalpak May 25 '13 at 07:32
  • `EDIT (17/5/2013): I get majorly frustrated by people getting their questions answered and their problems solved, but never "accepting" an answer :( (I'll get used to it, I suppose...)` It was just that he came first :) – An SO User May 25 '13 at 07:33
2

There are 3 ways to terminate a thread:

  1. The thread has finished the work it is designed to do, and exits the run() method naturally.
  2. The thread has received an interruption signal, while doing its work. It decides to not continue with work and exits the run() method. It may also decide to ignore the signal and continue to work.
  3. The thread has been marked as daemon thread. When the parent thread who created this thread terminates, this thread will be forcefully terminated by the JVM.

See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.

http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

The way they recomend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136