This discussion is archived
1 2 3 5 Previous Next 74 Replies Latest reply: Jun 13, 2007 12:03 PM by 796440 RSS

Thread not responding to stop()

807605 Newbie
Currently Being Moderated
Hi, i'm in the midst of writing my first application, a Blackjack game. I'm having a problem with InterruptedExceptions being thrown when I call Thread.sleep() from within one of my threads.

Is there a way I can find out which thread is being interrupted by which other thread?

Upon running the Java debugger, i've noticed that the thread number continually increases. It gets greater as I run the application and never stops increasing, like so:

Thread-3[1] next
>
Breakpoint hit: "thread=Thread-4", BlackjackPanel$CardPanel.run(), line=453 bci=
0
453                     if (doDealAnimation)
Thread-4[1] next
Here's an example of how I call stop() and the following line is still executed:
Step completed: "thread=Thread-3", BlackjackPanel$CardPanel.run(), line=533 bci=
417
533                                                     stop();

Thread-3[1] next
>
Step completed: "thread=Thread-3", BlackjackPanel$CardPanel.run(), line=534 bci=
421
534                                                     return;
The complete source for this application is at: http://kouellette16.home.comcast.net/MyBlackjackGame__6-13-07.zip

Thank you for your time.
  • 1. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    Thread.stop() is deprecated.

    Click here to see why.
  • 2. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    Yeeaahhh... i'm aware of that. I've already overidden the stop method.
              private void stop()
              {
                   if (thread != null)
                   {
                        thread.interrupt();
                        thread = null;
                        //System.out.println("Stopping thread");
                   }
              }
    Thanks for the super-helpful post.
  • 3. Re: Thread not responding to stop()
    abillconsl Explorer
    Currently Being Moderated
    try:
    public class OuterClass {
      private InnerThread it;
    /* ... */
      private class InnerThread  extends Thread {
        boolean keepGoing;
        private InnerThread() {
           keepGoing = true;
        }
        /* ... */
        public void run() {
          while ( keepGoing ) {
            /* ... */
          }
        }
        public void stopIt() {
          keepGoing = false;
        }
      }
    /* ... */
      public void someOtherMethodThatUsesInnerThread() {
        /* ... */
        it = new InnerThread();
        it.start();
        doSomeOtherMethodThatProducesSomeOutcome();
      }
      private void doSomeOtherMethodThatProducesSomeOutcome() {
        /* ... */
        it.stopIt();
      }
    }
  • 4. Re: Thread not responding to stop()
    796440 Guru
    Currently Being Moderated
    Yeeaahhh... i'm aware of that. I've already overidden
    the stop method.
    [snip]
    Thanks for the super-helpful post.
    Wow. Somebody's got his tampon stuck crossways today.
  • 5. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    Yeeaahhh... i'm aware of that. I've already overidden
    the stop method.

    Thanks for the super-helpful post.
    Then you're talking about a Runnable, right? Thread.stop() is also final, so you can't override it. If you're implementing a Runnable, then you're not overriding stop().

    Thanks for the smart-ass comment, though.
    public class DieThread {
    
        class NiftyThread implements Runnable {
    
            private boolean die;
            private int blah;
    
            public void run() {
                while (!die && blah < 100) {
                    System.out.printf("\b\b\b\b\b\b\b\b\b\bBlah. %3d%%", blah++);
                    try {Thread.sleep(10);} catch (InterruptedException e) {/*gulp*/}
                }
            }
    
            public void stop() {
                die = true;
            }
        }
    
        public DieThread() {
    
            NiftyThread myThread = new NiftyThread();
            (new Thread(myThread)).start();
    
            try {Thread.sleep(1000);} catch (InterruptedException e) {/*gulp*/}
            myThread.stop();
    
        }
    
        public static void main(String[] args) {
            new DieThread();
        }
    
    }
    EDIT: How about doling out some Dukes, there, tough guy? I'm pretty sure abillconsl solved your problem for you.
  • 6. Re: Thread not responding to stop()
    abillconsl Explorer
    Currently Being Moderated
    Thanks for that kev ... OP, why not split em up for us.
  • 7. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    In my opinion and considering the deprecations of the Thread API, I consider using any idea of "stopping" or "killing" a thread to be bad practice. Here's the scenario I would prefer:
    public class NiceRunnable implements Runnable {
        public void run() {
            try {
                for(int i = 0; i < 100 && !Thread.currentThread().isInterrupted(); ++i) {
                    System.out.println(i);
                    Thread.sleep(10);
                }
            } catch(InterruptedException e) {
                //We must not forget that catching the InterruptedException clears the interrupted flag
                //Thus the try/catch has to be outside of the loop
            }
        }
    }
    Using this kind of Runnable, all we need to do to get the Thread to stop execution is
    Thread t = new Thread(new NiceRunnable());
    t.start();
    t.interrupt();
    And if we wish to block the execution until we are sure that the Thread has completely stopped, we only need to call t.join().
  • 8. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    Oh and before anyone asks... The reason for using interrupt instead of adding yet another boolean is that the Java API already relies on the interrupted flag to break out of blocking calls such as ServerSocket.accept(), InputStream.read() and so on... So the interrupt solution will work wherever you are inside the execution of a Runnable. Blocked on an API call or running through your own loops.
  • 9. Re: Thread not responding to stop()
    796440 Guru
    Currently Being Moderated
    Oh and before anyone asks... The reason for using
    interrupt instead of adding yet another boolean is
    that the Java API already relies on the interrupted
    flag to break out of blocking calls such as
    ServerSocket.accept(), InputStream.read()
    The downside is that the interrupt can occur at any point, so it can be harder to clean up. The boolean lets you control exactly when the thread will be told it's time to stop.
  • 10. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    The downside is that the interrupt can occur at any
    point, so it can be harder to clean up. The boolean
    lets you control exactly when the thread will be told
    it's time to stop.
    The interrupt can occur at any point, but since you're the one responsible for checking the interrupted flag, it is easy to figure out what cleanup has to be done. Unlike some believe, interrupt doesn't actually stop a Thread, it just raises a flag which should be queried regularly by any Thread so that it knows it has been requested to stop in a deterministic manner.

    An example which illustrates this is the following:
    public class NastyRunnable implements Runnable {
        public void run() {
            while(true) {
                System.out.println("haha I'm still alive");
            }
        }
    }
    Try running this in a thread and then interrupting it and you'll see the result.
  • 11. Re: Thread not responding to stop()
    796440 Guru
    Currently Being Moderated
    The downside is that the interrupt can occur at
    any
    point, so it can be harder to clean up. The
    boolean
    lets you control exactly when the thread will be
    told
    it's time to stop.
    The interrupt can occur at any point, but since
    you're the one responsible for checking the
    interrupted flag, it is easy to figure out what
    cleanup has to be done. Unlike some believe,
    interrupt doesn't actually stop a Thread, it just
    raises a flag which should be queried regularly by
    any Thread so that it knows it has been requested to
    stop in a deterministic manner.
    I know there are some conditions when it raises the flag and some when it throws the exception, but I haven't used it for a while, so I don't recall the details.

    If it only throws the exception when it's in a blocking call, else raises flag, then yes, we can dispense with the additional boolean.

    ...


    Okay, I just looked. InterruptedException and the various I/O exceptions that can be thrown by interrupt() are checked, so they can't occur anywhere in your code where you're not expecting them.

    However, if you want pure flag behavior--that is, if the interrupt occurs while blocked and you want to ignore it, complete that read or whatever, complete that iteration of your loop, and just wrap up at the end, then you'll need to set another flag in the catch block. Or maybe just interrupt() again, which will raise the flag this time?
  • 12. Re: Thread not responding to stop()
    807605 Newbie
    Currently Being Moderated
    Exactly, the InterruptedException is the way the Java API uses to break out of its blocking methods. It won't be thrown in your face out of the blue.

    As for allowing the completion of an iteration of a loop before really interrupting your Thread, you will in fact need another internal flag of yours. Although this still is better than the previous approach with a custom stop method since calling interrupt will allow you to break out of your own code, or to break out of a blocking API call. On the other hand, the stop method shown earlier wouldn't make it possible to break out of a blocking API call.

    Finally, another advantage of relying on "interrupt" to stop a Thread is that you can benefit from the abstraction of handling a Collection of Threads and stop them without knowing any specific implementation details such as a custom stop method.


    I think I'll write an sdnshare article on the subject ;)
  • 13. Re: Thread not responding to stop()
    abillconsl Explorer
    Currently Being Moderated
    Boise I da know ... Joshua Bloch seems to use the older method alot in his section on Threading.
  • 14. Re: Thread not responding to stop()
    796440 Guru
    Currently Being Moderated
    As for allowing the completion of an iteration of a
    loop before really interrupting your Thread, you will
    in fact need another internal flag of yours.
    Nope. Just call interrupt() in your catch block and test interrupted() at the end (or beginning) of your loop. See code below.

    :-)


    Finally, another advantage of relying on "interrupt"
    to stop a Thread is that you can benefit from the
    abstraction of handling a Collection of Threads and
    stop them without knowing any specific implementation
    details such as a custom stop method.
    Although you do have to know that they respond to interrupt properly. Still a good point though.
    import java.util.*;
    
    public class InterruptTest {
      public static void main(String[] args) throws Exception {
        Random rand = new Random();
        while (true) {
          Thread th = new Thread(new Task());
          th.start();
          Thread.sleep(rand.nextInt(200) * 10);
          System.out.println("main interrupting task");
          th.interrupt();
          th.join();
        }
      }
    }
    
    class Task implements Runnable {
      public void run() {
        while (true) {
          System.out.println(new Date());
    
          try {
            Thread.sleep(250);
          }
          catch (InterruptedException exc) {
            System.out.println("Interrupted, re-interrupting");
            Thread.currentThread().interrupt();
          }
    
          for (int ix = 0; ix < 200000000; ix++) {
            int jx = ix * ix;
            if (ix % 1000000 == 0) {
              Thread.yield();
            }
          }
          
          if (Thread.interrupted()) {
            System.out.println("Interrupted, ending");
            break;
          }
        }
      }
    }
    Wed Jun 13 11:18:34 PDT 2007
    main interrupting task
    Interrupted, ending
    Wed Jun 13 11:18:38 PDT 2007
    main interrupting task
    Interrupted, re-interrupting
    Interrupted, ending
    Wed Jun 13 11:18:41 PDT 2007
    main interrupting task
    Interrupted, ending
    Wed Jun 13 11:18:44 PDT 2007
    main interrupting task
    Interrupted, ending
    Wed Jun 13 11:18:47 PDT 2007
    We can see that both the InterruptedException being caught and re-raising the flag by us calling interrupt() and the flag being raised by interrupt() being called when we're not blocking can be handled by checking interrupted() at the end of the loop.
1 2 3 5 Previous Next