CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: Kill a thread

  1. #1
    Join Date
    Jan 2005
    Posts
    4

    Kill a thread

    Hi,

    Discussions on stopping threads have been up on this forum before but I feel my particular case hasn't been aswered yet.

    I have a program that makes a methodcall that sometimes doesn't return for a long period of time. There are users waiting for the program to produce a response and they aren't prepared to wait for to long.

    I want to be able to return a response within a specified amount of time regardless of if the method returned or not. If the method prouduces a result, fine, then I'll show that to the users. But after a specified amount of time, if the method hasn't returned a response, I want to tell the users that a result isn't possible to produce at the moment.

    To solve this problem the mainMethod starts a thread that executes the methodcall. The main program don't wait for more than the specified amount of time. If no result has been produced by the thread at that time a null result is returned. If the thread produces a result within the timeframe it is returned to the users.

    This is the way I do this:
    Code:
    public class Worker implements Runnable {
      private String result;
      public run() {
        result = blockingMethodCall();
      }
      public String getResult() {
        return result;
      }
    }
    public class MainProgram {
      public void mainMethod() {
        ...
        Worker worker = new Worker();           
        Thread thread = new Thread(worker); 
        thread.start();
        // Returns when finished executing, or after maximum TIME_OUT time
        thread.join(TIME_OUT);                        
        if (thread.isAlive()) {
          // If the thread is still alive, it's still blocking on the methodcall, try stopping it
          thread.interrupt();
          return null;
        } else {
          // The thread is finished, get the result
          return worker.getResult();               
        }
      }
    }
    My problem is that the call to interrupt() doesn't stop the thread. When mainMethod returns, the thread will still be alive in the VM. Since there might be hundreds of calls to mainMethod every hour, several hundreds of threads will be out there blocking on that method and eating up the resources of the server. And there will be more and more as time passes.

    So, how will I solve this problem? If I at least could kill of the thread...

  2. #2
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104

    Re: Kill a thread

    there are two threads in your scenario, the main, and the child. the main thread halts at the point you call join() and waits for the child thread to finish (return from its run() method).

    if the child thread is still working when the timeout expires, the main thread issues an interrupt() to it, and the child thread (if it is blocked, which it ought to be) will stop what it is doing, unblock, and receive an InterruptedException

    it is at this stage in your run() method, that you would handle the receipt of an InterruptedException, set some class variable to the answer, or null if there was no answer, and then return from run

    immediately after the join the main thread should check the child thread for the answer. it can also check the thread for being isInterrupted() which will give you a true or false indicating if the thread was interrupted or not.. this is probably a moot point though, because if youre setting an answer to null if there was no answer due to interruption, then you dont need to check for isInterrupted() as the answer implies the thread was interrupted. If however, null is a valid answer and cannot be relied upon to imply interruption, then isInterrupted() might be of some use

    after the child thread has returned from its run() it will do no more work unless it is started again. you may wish to pool it, or you can just get rid of it by setting the thread object to null and waiting for the garbage collector to eat it..


    thread stopping and killing is not a good idea, and usually unnecessary because in nearly all cases, it is possible to have a thread exit from its run() method whether it finished its work or not. as there is only one exit point, that can be made to pass through a finally{} block, you can control the amount of mess the thread leaves behind (i.e. it shouldnt)
    in your code, your isAlive() check is unnecessary.. you should simply check whether the thread delivered an answer or not, then dispose of it via usual java garbage collection. it would be the child thread's resposibility to close network conenctions etc that it had made
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  3. #3
    Join Date
    Jan 2005
    Posts
    4

    Re: Kill a thread

    Thanks for your help so far...

    Quote Originally Posted by cjard
    if the child thread is still working when the timeout expires, the main thread issues an interrupt() to it, and the child thread (if it is blocked, which it ought to be) will stop what it is doing, unblock, and receive an InterruptedException
    Yes, you would think so, but it doesn't. When I do thread.interrupt(), nothing happens in the workers run method. It is still stuck on this line as far as I can see
    Code:
    BufferedReader br = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
    This is the whole method:
    Code:
    try {
      HttpURLConnection connection = HTTPSclient.getConnection(url, authorization);
    
      // Other configuration
      connection.setRequestMethod( "GET" );
      connection.setRequestProperty( "Content-Type", "text/xml" );
      connection.setUseCaches( false );
    
      //Get the response from the server and write it to a String
      BufferedReader br = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
      String tempLine;
      String str = "";
      while( ( tempLine = br.readLine() ) != null ) { 
        str += tempLine + "\n"; 
      }
      result = URLDecoder.decode( str, "UTF-8" );
    } catch (IOException e) {
      exception = e;
    }
    Quote Originally Posted by cjard
    it is at this stage in your run() method, that you would handle the receipt of an InterruptedException, set some class variable to the answer, or null if there was no answer, and then return from run
    I've tried putting a catch clause in to catch InterruptedException like this:
    Code:
    ...
      result = URLDecoder.decode( str, "UTF-8" );
    } catch (InterruptedException ie) {
      System.err.println("Got interrupted");
    } catch (IOException e) {
      exception = e;
    }
    just to try it, but the compiler says "Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body.
    Where am I supposed to put the catch clause for InterruptedException as you suggest?
    Quote Originally Posted by cjard
    after the child thread has returned from its run() it will do no more work unless it is started again. you may wish to pool it, or you can just get rid of it by setting the thread object to null and waiting for the garbage collector to eat it..
    I'll do that.

  4. #4
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104

    Re: Kill a thread

    does a call to connect() on the HttpURLConnection take a similarly long amount of time to connect?

    how long does it tale you to establish a connection via telnet to this particular host?
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  5. #5
    Join Date
    Dec 2004
    Location
    China
    Posts
    1

    Re: Kill a thread

    I think any kind of IO blocking is highly depending on the operating system API and JVM. As far as I know, most subclass of InputStream ignore interrupts except PipedInputStream throw an InterruptedIOException. The thread doesn’t even respond when you stop it!!!!

    It’s easy to test, replace your code by read the stream from System.in and print them out right after the thread get the input. DO NOT input anything while the main thread is waiting. Even after your main thread exit, the working thread is still waiting for you input and isAlive() return false. Input something and press enter, the "dead" thread print them out!!!!!! While you may get different result with different System and JVM version.

    an easy way to handle this is using the close() method from another thread to stop the InputStream, if it doesn't work close the HttpConnection, and event the socket.... the higher level class you use, the more chance the stream throw an exception.

    NOTE: invoking close() on an InputStream may sometimes block when read() and close() are synchronized.

    I am not a native English speaker, hope you can understand me.

  6. #6
    Join Date
    Aug 2009
    Posts
    1

    Re: Kill a thread

    I am sure that this problem must have solved long back, after all 5 years got over. But the simple answer for this kind of problems where InterruptedException cannot be handled is by creating a stop method in child thread class and inside that closing the resources which are being read by the child thread. For ex. HttpURLConnection connection and BufferedReader br should be declared as a class variable and inside the stop() method, these should be closed and nullified. From the calling thread, inside the thread.isAlive()
    call the stop() method of child thread instead of interrupt. This will remove the hanging thread It worked well for me.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured