Results 1 to 12 of 12
  1. #1
    SUSHMA50 is offline Member
    Join Date
    Jan 2009
    Posts
    2
    Rep Power
    0

    Default Stopping a running thread in a multithreaded environment

    Hi,
    I am new to this forum and Java threading too. I have an application where a thread is spawned each time a user fires a query on a database from the UI by clicking on execute button. When clicking on execute button I am not maintaining the details of the thread object created any where. I can cancel a particular thread out of many threads spawned. So how can I stop that particular thread.

    Thanks and Regards
    Siddharth Shah

  2. #2
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    First, you need to track your threads. I would use a HashMap<String, Thread>, where the key would provide some means of identifying the thread.

    In general, your worker threads should avoid blocking for long periods. That way, you can periodically test a flag that tells the thread to return from its run() method. This allows the thread to clean up its resources without using exceptions.

    If the database operations themselves run for a long time and thus block, you can use thread.interrupt(). This will cause an exception if the thread is currently blocked, or it will set the thread's interrupted property, which must be checked in a loop. Interrupted exceptions that are thrown during a database operation will stop the operation and possibly the connection, so exception checking while releasing resources is important.

    Remember to synchronize everything appropriately; in particular, the HashMap and any flags you set in your thread objects.

  3. #3
    SUSHMA50 is offline Member
    Join Date
    Jan 2009
    Posts
    2
    Rep Power
    0

    Default

    Hi Steve,
    Thanks for the response. i have created a hash Map but what will be the contents of the value. Is it a thread object or we can only store the thread Id. Also how will I set the value of the boolean variable for this thread as I just want to stop this thread and not the other threads

    Thanks
    Siddharth Shah

  4. #4
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Each thread is based on an instance of the Thread class. You control the thread through the instance.

    When you instantiate thread, you specify an instance of a class that implements Runnable, which basically means it provides a public void run() method. myThread.start() causes the objects run() method to be invoked; the thread runs until the run() method returns.

    By keeping track of the Thread class instances, you can control the thread and set fields in the object.

  5. #5
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Note that Thread.interrupt() will only interrupt the thread if it is actually sitting in a call that can throw InterruptedException! (See my page on thread interruption.)

    If your Java thread is sitting waiting for a long-running SQL query, I think the cleanest way to wake up that thread would be to kill the query via the database. If you couldn't do that, you could try closing the Statement/Connection, but if you do that you run the risk of leaving a dangling thread running on the database (the best thing to do is really to see what actually happens on the particular database/configuration you're using).

  6. #6
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Here is a general construct I often use for threads I want to be able to kill. Doesn't need to be generic, just to demonstrate the principles...

    public class WorkThread<T> extends Thread {
    boolean keepGoing = true;
    boolean workAvailable = false;
    T work;

    /**
    * Call this method to post new work to the thread
    */
    public synchronized void moreWork(T work) {
    this.work = work;
    workAvailable = true;
    notifyAll();
    }

    public synchronized void run() {

    while(keepGoing) {
    while(!workAvailable) {
    try {
    wait();
    } catch (InterruptedException ex) {}
    }

    if(!keepGoing) break;

    doWork(work);

    workAvailable = false;
    }

    notify();
    }

    /**
    * Call this method to cause the thread to quit gracefully
    */
    public synchronized void quit() {
    keepGoing = false;
    try {
    wait();
    } catch (InterruptedException ex) {}
    }

    /**
    * Implement this to do some work
    */
    void doWork(T work) {
    ...do something usefull here...
    }
    }

  7. #7
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    I like your concept, especially your use of wait() to minimize overhead while the thread has nothing to do.

    A noticed a couple things about the specific code.

    While there is not more work, you wait. When quit is called, you set a flag, and then you wait. Unless some other thread notifies on the instance itself, you have a deadlock. You need to notify in quit() before waiting.

    Note also that, if you notify, keepGoing may not be synchronized before run() tests it again; you have a race condition. This seems like a good time to use volatile (first time I've ever said that...)

    You synchronized the run() method. Given that you wait almost immediately, I *think* that will end synchronization. If you didn't wait, then run() would lock the thread instance until the thread stopped. Whoever called quit() would be stopped. Better not to synchronize run(), since it really doesn't gain you anything.

    moreWork() will cause problems if it is called before the previous work is complete. Better to use an ArrayList<Work> to queue up the requests.

    I realize you need to synchronize to use wait(), even if you make keepGoing volatile. I suggest creating an instance variable

    private final Object _SyncObject = new Object();

    and use synchronize(_SyncObject) {} blocks. It just gives you more specific control over synchronization.

    Having said all that, I'm going to file this one away...

  8. #8
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Both 'run' and 'quit' are synchronized. When the while loop in 'run' exits (as a result of quit being called), it issues a notify. This interrupts the 'wait' in the quit method. The only way to get a deadlock here is if there is a runtime exception in the 'while' loop. A simple try/catch (Throwable...) in or around the doWork method would prevent that possibility.

    It's critical to synchronize all the methods I synchronized here. 'wait' gives up the lock until it gets a notify. At that point, it enters the competition for the lock.

    In this code fragment, the only way the 'wait' in the while loop will ever wake up is if there is new work, or if quit has been called (assuming you're not trying to shoot yourself in the foot by doing notify externally. If that's a concern, then you could use a private lock object instead). If it's new work, then keepGoing will still be set and so doWork will be called. If the notify was the result of 'quit', then keepGoing will be false, the while loop will exit, and the notify at the end of 'run' will wake the quit method back up.

    The advantage of doing this, is that when 'quit' returns, you are guaranteed that the thread has actually exited and any work it may have been working on has actually finished. The construct is also about as efficient as you can get without going into exotic methods of trying to avoid locks.

    You could certainly use a List of some kind to queue work up if you wanted.

  9. #9
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    I did notice that I made an error on the inner while loop....serves me right for going from memory...

    It should be

    while(keepGoing && !workAvailable) rather than just while(!workAvailable)

  10. #10
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Let me say again, I *really* like this solution.

    Here's my main point.

    The worker thread is waiting in the run() method.

    quit() in invoked on another thread, which updates the keepGoing flag. (I'll set aside the question about when local copies are updated.)

    The invoking thread starts waiting in quit().

    There is no notifyAll() in quit(), so now both threads are waiting. *Unless* entering a wait state or releasing a lock implicitly causes some sort of notify(); I don't believe that happens.

    The simple solution is to

    First, make keepGoing volatile, so there is no concern about local copies. OK, I lied.

    Java Code:
    public synchronized void quit() {
      keepGoing = false;
      [B]notifyAll();[/B]
      try {
        wait(); 
      } catch (InterruptedException ex) {} 
    }

  11. #11
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Thanks for pointing that out. Yes, the quit method needs a notify in it. Next time I post code here, I'll not go from memory, but will cut and paste operational code.

  12. #12
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Then you will be better than me. I've posted code, thought about it, and then had a big "Doh!" moment.

Similar Threads

  1. Pong Paddle Not Stopping Ball At Certain Speed
    By JDCAce in forum Java Applets
    Replies: 2
    Last Post: 10-12-2008, 06:15 AM
  2. Running a thread on another appilcation
    By Charlie in forum Advanced Java
    Replies: 2
    Last Post: 08-12-2008, 01:28 AM
  3. stopping thread...using flags
    By rstepler in forum New To Java
    Replies: 1
    Last Post: 07-31-2008, 10:36 PM
  4. A simple multithreaded server
    By Java Tip in forum java.net
    Replies: 0
    Last Post: 04-07-2008, 09:15 PM

Posting Permissions

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