Results 1 to 12 of 12
- 01-18-2009, 02:14 PM #1
Member
- Join Date
- Jan 2009
- Posts
- 2
- Rep Power
- 0
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
- 01-18-2009, 06:21 PM #2
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.
- 01-18-2009, 06:52 PM #3
Member
- Join Date
- Jan 2009
- Posts
- 2
- Rep Power
- 0
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
- 01-18-2009, 07:08 PM #4
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.
- 01-18-2009, 07:24 PM #5
Senior Member
- Join Date
- Nov 2008
- Posts
- 286
- Rep Power
- 5
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).Neil Coffey
Javamex - Java tutorials and performance info
- 01-23-2009, 06:48 AM #6
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
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...
}
}
- 01-23-2009, 03:27 PM #7
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...
- 01-24-2009, 03:07 AM #8
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
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.
- 01-24-2009, 03:10 AM #9
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
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)
- 01-24-2009, 06:14 AM #10
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) {} }
- 01-25-2009, 05:07 AM #11
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
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.
- 01-26-2009, 12:22 AM #12
Similar Threads
-
Pong Paddle Not Stopping Ball At Certain Speed
By JDCAce in forum Java AppletsReplies: 3Last Post: 04-01-2009, 11:07 PM -
Running a thread on another appilcation
By Charlie in forum Advanced JavaReplies: 2Last Post: 08-12-2008, 12:28 AM -
stopping thread...using flags
By rstepler in forum New To JavaReplies: 1Last Post: 07-31-2008, 09:36 PM -
A simple multithreaded server
By Java Tip in forum java.netReplies: 0Last Post: 04-07-2008, 08:15 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks