I have a long running task, something like:
public void myCancellableTask() {
while ( someCondition ) {
checkIfCancelRequested();
doSomeWork();
}
}
The task can be cancelled (a cancel is requested and checkIfCancelRequested() checks the cancel flag). Generally when I write cancellable loops like this, I use a flag to indicate that a cancel has been requested. But, I know I could also use Thread.interrupt and check if the thread has been interrupted. I'm not sure which would be the preferred approach and why, thoughts?
thanks,
Jeff
One problem with using interrupt is that if you do not control all code being executed, you run the risk of the interrupt not working "properly" because of someone else's broken understanding of how to handle interrupts in their library. That is the API invisibly exports an API around its handling of interrupts which you become dependent on.
In your example, suppose doSomeWork was in a 3rd-party JAR and looks like:
public void doSomeWork() {
try {
api.callAndWaitAnswer() ;
}
catch (InterruptedException e) { throw new AssertionError(); }
}
Now you have to handle an AssertionError (or whatever else the library you are using might throw). I've seen experienced developers throw all sorts of nonsense on receiving interrupts! On the other hand, maybe the method looked like this:
public void doSomeWork() {
while (true) {
try {
return api.callAndWaitAnswer() ;
}
catch (InterruptedException e) { /* retry! */ }
}
}
This "improper handling" of interrupt causes your program to loop indefinitely. Again, don't dismiss this as ridiculous; there are a lot of broken interrupt handling mechanisms out there.
At least using your own flag will be completely invisible to any 3rd-party libraries.
Interrupt will blast the thread out of a list of specified wait conditions. Your own cancel flag will not. If you want to interrupt waits on IO and events, use interrupt. Otherwise use your own.
It depends on the doSomeWork() implementation. Is that pure computation or does it (at any point) involve blocking API (such as IO) calls? Per bmargulies's answer, many blocking APIs in JDK are interruptible and will propagate the interrupted exception up the stack.
So, if the work entails potentially blocking activities, you need'll to take interrupts into consideration even if you decide to control the process using a flag, and should appropriately catch and handle/propagate the interrupts.
Beyond that, if relying on a flag, make sure your flag is declared with volatile semantics.
I think that it's a matter of preference in most cases.
Personally I would go for the hand-made flag. It gives you more control - for example, this way you make sure that your thread doesn't leave some other object in an inconsistent state.
Besides, if performance is really critical, bear in mind that using exceptions has an overhead (even if it's negligible in 99% of the cases).
First, let's take a look at the usage conditions.
If we have a thread pool and use interruption as the cancellation mechanism, we can only interrupt the worker threads through the pool. In other words, we can't directly invoke Thread.interrupt since we don't own the threads. So, we must acquire a Future and invoke Future.cancel. Or we must call ExecutorService.shutdownNow to cancel all tasks interrupting the busy threads. In the first case, it requires some bookkeeping on our side to hold the Future handles. So the application must keep new tasks and remove the old ones.
On the other hand, if you use a global cancellation flag, we can cancel/stop multiple tasks from a central place without additional bookkeeping. But if we want to cancel an individual task - similar to invoking Future.cancel - we must store a cancellation flag for each task.
Secondly, let's examine the general convention.
Java class libraries generally interpret a thread interrupt as a cancellation request. For example, LinkedBlockingQueue.take can make our program block. But when the current thread is interrupted it throws an InterruptedException and returns. So our application becomes responsive by using a responsive method. So we can just build upon the already existing support and write additional Thread.interrupted/Thread.currentThread().isInterrupted checks in our code.
Moreover, the cancellation methods in ExecutorService use thread interruption. As we mentioned, Future.cancel and ExecutorService.shutdownNow rely on interrupts.
Related
I would like to shutdown a thread gracefully. However, once the shutdown is initiated the thread should perform some shutdown operation after ending usual operation.
Both threads use sleeps and/or wait and handle InterruptedException, they also work on tasks in a loop taking only a few milliseconds. So that I expected the while loop to end because Thread.currentThread().isInterrupted() becomes "true".
The problem is that with my code sometimes I get the log "SHUTDOWN" and sometimes not. Also I get "INTERRUPTED" only sometimes, which I understand of course. With another similar thread I never get the "SHUTDOWN".
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new Test());
Thread.sleep(10000);
executor.shutdown();
try {
if(this.executor.awaitTermination(60, TimeUnit.SECONDS)) {
this.loggerFactory.getLogger(this.getClass()).info("CLOSED (GRACEFULLY)!");
} else {
this.executor.shutdownNow();
this.loggerFactory.getLogger(this.getClass()).info("CLOSED (IMMEDIATELY)!");
}
} catch(InterruptedException e) {
this.executor.shutdownNow();
this.loggerFactory.getLogger(this.getClass()).info("CLOSED (IMMEDIATELY)!");
}
class Test implements Runnable {
private volatile boolean isRunning = true;
#Override
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
while(!this.isRunning) {
synchronized(this) {
this.wait();
}
}
// DO SOMETHING LASTING A FEW MILLISECONDS
Thread.sleep(500);
}
} catch(InterruptedException e) {
this.loggerFactory.getLogger(this.getClass()).info("INTERRUPTED!");
}
this.loggerFactory.getLogger(this.getClass()).info("SHUTDOWN!");
// DO SOME SHUTDOWN OPERATION
}
}
EDIT:
After some commentary by OP, an entirely different and much superior solution seems to be available:
Use hooks!
Java has a system to 'install' a shutdown hook. These are called when the VM shuts down... sometimes. If you get SIGTERMed (kill -9) or someone trips over a powercable, or linux kills your process due to excessive memory use, or the kernel dumps, or your VM hard crashes (for example, a core dump in native code), or the device loses power, they don't get called, of course.
But, if someone in the process runs System.exit(), or all non-daemon threads are done, or someone hits CTRL+C or sends SIGKILL (kill, not kill -9) to your process, they get run first, and only when they all finish does the java process actually end.
That sounds like a vastly superior solution here. Your shutdown hook should:
acquire the lock on some private AtomicBoolean.
set the boolean to false (the boolean indicates: May I query this sensor?)
release the lock.
reset the sensor.
return.
And all your normal operation code that reads that sensor should:
acquire a lock on the boolean.
if false, throw or otherwise abort.
perform the sensor read operation.
release the lock.
Nothing should ever touch that sensor without holding the lock (failure to do this would imply maybe messing with that sensor after you've already reset it, which would be bad).
original answer:
I would like to shutdown a thread gracefully.
Why? 'gracefully' is a very nice sounding word, but once you dig into what it means, it's just nasty things. It's a word that means: "That will cause my software to fail, possibly persistently (as in, won't start anymore without cleaning up stuff), if someone trips over a powercable or my app hard-crashes".
A much better design is to have a thread that doesn't need to be shut down. Just pull the plug on it, and all is well.
For example, old filesystems (MS-DOS and early windows age) required graceful shutdowns; failure to do so would lead to persistent issues - the system wouldn't boot at all, you bricked the box. They then had mitigation systems in place (chkdsk systems), but modern OSes are much better. Their filesystem handling setup mostly doesn't care about being 'gracefully' shut down. Just pull the plug on em, they'll be fine, that's what journals do.
So that I expected the while loop to end because Thread.currentThread().isInterrupted() becomes "true".
That's not how you're supposed to use that API.
Here's the basic gist of what the interrupted API does:
Any thread can 'raise the interrupt flag' on any other (someThread.interrupt()).
raising the flag doesn't do anything other than raise the flag, unless a method explicitly decides to look at it.
The method Thread.interrupted() is how you're supposed to read the flag out in order to act upon it, __and not Thread.currentThread().isInterrupted(). The former will check the flag and clear it. The latter merely checks the flag.
Some java methods are specced to respond to the flag being up. You recognize these methods because they throws InterruptedException. There may be more methods; for example, on most OSes, interrupting a thread currently waiting for more bytes to flow in from the network (they are blocked on a read() call on an InputStream obtained from socket.getInputStream()) WILL cause that read call to fail (with an IOException, not an InterruptedException, because read() isn't specced to throw InterruptedEx), but that's no guarantee; on some OSes, it won't, and you can't interrupted that.
The general policy is that the moment you handle an interrupted flag, you lower the flag, and java code does just that: If a method throws InterruptedEx, the flag will be cleared.
Java does not define what you should do if interrupted. Threads don't get magically interrupted; for example, when your VM shuts down (someone hits CTRL+C), that doesn't interrupt any threads whatsoever. Java will just 'pull the plug' on all threads. That's because this is better (see above). Therefore, if a thread is interrupted, that's because you wrote thread.interrupt() someplace, therefore, you decide what it means. Maybe it means 're-read a config file and restart the server listening process'. Maybe it means 'stop calculating chess moves and perform the best move found so far'. Maybe it means 'recheck for a condition'. Maybe it means 'end the thread entirely'. It's up to you. There is no standard.
Note that the various methods specced to respond to interrupt flags (such as wait(): It throws InterruptedException) all share this property: If you call them while the flag is up, they will instantly return by throwing InterruptedException, they never even begin waiting.
So, for your code, given that you wait() already, just make that while(true) and rely on the InterruptedEx.
I was reading about ways to end a thread in https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html, which is a link I found from the question How do you kill a thread in Java?
In the first link, they first discuss using a volatile variable to signal to the thread that you want to terminate. The thread is supposed to check this variable and cease operation if the variable has a value that means cease (e.g. if it is null). So to terminate the thread, you would set that variable to null.
Then they discuss adding interrupts to help with threads that block for long periods of time. They give the following example of a stop() method that sets the volatile variable (waiter) to null and then ALSO throws an interrupt.
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}
I am just wondering, why would you need both? Why not ONLY use interrupt(), and then handle it properly? It seems redundant to me.
(First part of this is in general, arguably I was not paying attention to the specifics of the question. Skip to the end for the part that addresses the techspec discussed in the question.)
There is no good technical reason. This is partly about human limitations and partly about confusing api design.
First consider application developers’ priority is creating working code that solves business problems. Thoroughly learning low level apis like this gets lost in the rush to get work done.
Second there’s a tendency when you’re learning things to get to a good enough state and leave it there. Things like threading and exception handling are back-of-the-book topics that get neglected. Interruption is a back of the book topic for threading books.
Now imagine a codebase worked on by multiple people with varying skill level and attention to detail, who may forget that throwing InterruptedException from wait and sleep resets the interrupt flag, or that interrupted isn’t the same as isInterrupted, or that InterruptedIoException resets the interrupt flag too. If you have a finally block that catches IOException, you may miss that InterruptedException is a subclass of IOException and you could be missing out on restoring the interrupt flag. Probably people in a hurry decided to hell with it, I can’t count on this interrupted flag
Is it right? No.
The hand rolled flag doesn’t help with short circuiting wait or sleep the way interruption does.
the Java 5 concurrency tools expect tasks to use interruption for cancellation. Executors expect tasks submitted to them to check for interruption in order to quit gracefully. Your tasks may use other components, like a blocking queue. That queue needs to be able to respond to interruption, the thing using it needs to be aware of the interruption. The handrolled flag doesn’t work for this since the java 5 classes can’t know about it.
Having to use interruption because you’re using tools that expect it, but not having confidence in the flag value due to unmanageable technicalities, would lead to this kind of code.
(end of rant, now actually responding to the specific techspec example)
OK, looking at this techguide article in particular. Three things stand out:
1) it's not making use of interruption at all, except to cut the sleep time short. Then it just squelches the exception, and doesn't bother to restore the flag or check it. You could use the InterruptedException to terminate by catching it outside the while loop, but that's not what this does. This seems like a strange way to do this.
2) as the example is fleshed out it becomes clear the flag is being used to turn the waiting on and off. Somebody might use interruption for this but it's not idiomatic. So having a flag is ok here.
3) this is a toy example in a techguide. Not all the Oracle content is as authoritative as the techspecs or the API documentation. Some tutorials have misstatements or are incomplete. It might be the reason the code was written like this was that the author figured readers would not be familiar with how interruption worked and it was better to minimize its usage. Technical writers have been known to make choices like that.
If I rewrote this to use interruption I would still keep the flag; I'd use interrupt to terminate, and use the flag for suspend/resume functionality.
Please see this documentation.
Your thread should check thread.isInterrupted() status, for example:
Thread myThread = new Thread() {
#Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("I'm working");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//We would like also exit from the thread
return;
}
}
}
};
And when you would like to stop the thread, you should invoke
myThread.interrupt();
Besides we can use static method Thread.interrupted() that also checks the status but after that, the method clears it and you have to invoke again myThread.interrupt() to set the status again. But I don't recommend to use Thread.interrupted() method.
This approach helps gracefully stop the thread.
So I also do not see any reasons to use an additional volatile variable.
The same behavior can be reached via additional volatile flag as in #lexicore's answer, but I think it is redundant code.
#NathanHughes is completely right, but I am going to rephrase his long answer into few words: third-party code.
This is not just about "dumb junior developers", — at some point in application's life you will be using lots of third-party libraries. Those libraries will not gentlemanly respect your assumptions about concurrency. Sometimes they will silently reset interruption flag. Using separate flag solves that.
No, you can not get rid of third-party code and call it a day.
Suppose, that you are writing a library, — for example, ThreadPoolExecutor. Some of the code inside your library needs to handle interruption… Or even unconditionally reset the interruption flag. Why? Because previous Runnable is done, and a new Runnable is on the way. Unfortunately, at that point there may be a stale interruption flag, that was aimed… wait, whom was it for again? It could have been addressed for previous Runnable or for new (not yet running) Runnable, — there is no way to tell. And this is why you add isCancelled method to FutureTask. And unconditionally reset interruption flag before executing new Runnable. Sounds familiar?
Thread#interrupt is completely detached from the actual work units, running on that thread, so adding an additional flag is necessary. And once you have started doing so, you have to do that all the way — up to the outermost and down to the innermost work unit. In effect, running unknown user-supplied code on your threads makes Thread#interrupted unreliable (even if Thread#interrupt still works fine!)
I want a piece of code to run as long as the thread isn't interrupted. Currently what I'm doing is this:
while(!Thread.interrupted()){
// .. some code
try {
Thread.sleep(4000);
} catch(InterruptedException ex){
break;
}
// .. some more code
}
My question is: is this good practice? Is it appropriate use of interrupt?
Yes, I think this is the very purpose of interrupt(), so it seems like a legitimate usage.
Conceptually this is on the right track. There are some details that could be improved, though.
What's right about this is that the thread interruption mechanism is being used to tell the thread to do something else, and the thread can respond how it pleases at a time of its choosing. In this case, catching InterruptedException from Thread.sleep() and breaking out of the loop is an entirely reasonable thing to do. It's certainly much preferable to what is usually done, which is to ignore the exception entirely. (This is usually wrong.)
What might be an issue is that the loop condition also checks whether the thread has been interrupted. This might be a problem, depending on what some code and some more code are doing. Your system might be left in different states depending on which chunks of code have been executed when the interrupt is detected.
Unless one iteration of your loop runs for a really long time (aside from the sleep), it's usually only necessary for there to be a single interruption point in a loop. In this case, if the thread is interrupted while it's doing some code processing, an InterruptedException will be generated immediately upon the call to Thread.sleep(). So you could just change the loop condition to while (true) and have the catch-block break out of the loop. (If you do this, you should also reassert the interrupt bit; see below.)
Alternatively, if you only want to check for interrupts at the top of the loop, you could do this:
while (!Thread.interrupted()) {
// .. some code
try {
Thread.sleep(4000L);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
// .. some more code
}
This arranges there to be only a single exit point from the loop, which might makes the code easier to reason about.
Note the technique used here is to reassert the interrupt bit on the thread after having caught InterruptedException. The general rule about handling interrupts is that either the interrupt bit should be reasserted, or an InterruptedException should be propagated. If neither is done, then the calling code might end up blocked in a subsequent wait() call, with no knowledge that it had ever been interrupted. That's usually an error.
Good practice is to use the newer higher level APIs such as an ExecutorService instead. You shouldn't use the lower level APIs such as threads or synchronize or wait/notify.
I've come across the code below, and I'm wondering if it does exactly what I think it does:
synchronized(sObject) {
mShouldExit = true;
sObject.notifyAll()
while (!mExited) {
try {
sObject.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
About the context: there is another thread that checks for mShouldExit (inside the sObject monitor) and will exit in that case.
This does not look to be a correct pattern to me. If an interrupt happens, it will set the interrupted status again, so when it returns to sObject.wait(), another InterruptedException will come etc. etc. etc. Therefore, it can never go to truly waiting state (sObject.wait()) i.e. it will never release the sObject monitor. This may result in an infinite loop, as the other thread cannot set mExiting to true, because it can never enter sObject's monitor. (So I think that the interrupt() call is an error, it must not be used here.) Am I missing something?
Note that the code snippet is a part of the official Android framework source code.
UPDATE: actually, the situation is worse, because the same pattern is used in Android when your GL rendering starts. The official source code of GLSurfaceView.GLThread.surfaceCreated():
public void surfaceCreated() {
synchronized(sGLThreadManager) {
if (LOG_THREADS) {
Log.i("GLThread", "surfaceCreated tid=" + getId());
}
mHasSurface = true;
sGLThreadManager.notifyAll();
while((mWaitingForSurface) && (!mExited)) {
try {
sGLThreadManager.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
You can reproduce the bug in a similar way: make sure your UI thread has its interrupted status flag yet, then add your GLSurfaceView and start the GL rendering (via setRenderer(...), but on some devices, make sure your GLSurfaceView has Visibility.VISIBLE status, otherwise rendering will not start).
If you follow the above steps, your UI thread will end up in an infinite loop, because the above-quoted code will keep generating an InterruptedException (due to wait()) and therefore the GL thread will never be able to set mWaitingForSurface to false.
According to my tests, it seems that such an infinite loop will also result in an endless sequence of GC_CONCURRENT garbage collection (or, at least, such messages in logcat). Interesting, someone had an unknown poorly-defined issue on stackoverflow earlier which might be related:
How to solve GC_concurrent freed?
Isn't it possible that perhaps his UI thread had its interrupted flag set to true, and he was using a GLSurfaceView for the map he mentions? Just an assumption, a possible scenario.
Short version: That code is wrong, and will cause an infinite loop (I still have a doubt, but may depend on JVM implementations). Setting the interrupt status is the right thing to do, but it should then exit the loop, eventually checking that same interruption status using Thread.isInterrupted().
Long version for the casual reader:
The problem is how to stop a thread that is currently executing some work, in response to a "Cancel" button from the user or because of some other application logic.
Initially, Java supported a "stop" method, that preemptively stopped a thread. This method has been demonstrated to be unsafe, cause didn't give the stopped thread any (easy) way to clean up, release resources, avoid exposing partially modified objects and so on.
So, Java evolved to a "cooperative" Thread "interruption" system. This system is quite simple : a Thread is running, someone else calls "interrupt" on it, a flag is set on the Thread, it's Thread responsibility to check if it has been interrupted or not and act accordingly.
So, correct Thread.run (or Runnable.run, of Callable etc..) method implementation should be something like :
public void run() {
while (!Thread.getCurrentThread().isInterrupted()) {
// Do your work here
// Eventually check isInterrupted again before long running computations
}
// clean up and return
}
This is fine as long as all the code your Thread is executing is inside your run method, and you never call something that blocks for a long time ... which is often not the case, cause if you spawn a Thread is because you have something long to do.
The simplest method that block is Thread.sleep(millis), it's actually the only thing it does : it blocks the thread for the given amount of time.
Now, if the interrupt arrives while your thread is inside Thread.sleep(600000000), without any other suport, it would take a lot for it to arrive to the point where it checks isInterrupted.
There are even situations where your thread would never exit. For example, your thread is computing something and sending results to a BlockingQueue with a limited size, you call queue.put(myresult), it will block until the consumer free some space in the queue, if in the mean time the consumer has been interrupted (or died or whatever), that space will never arrive, the method will not return, the check on .isInterrupted will never be performed, your thread is stuck.
To avoid this situation, all (most) methods that interrupt the thread (should) throw InterruptedException. That exception simply tells you "I was waiting for this and that, but in the meanwhile the thread as been interrupted, you should do cleanup and exit as soon as possible".
As with all exceptions, unless you know what to do, you should re-throw it and hope that someone above you in the call stack knows.
InterruptedExceptions are even worse, since when they are thrown the "interrupted status" is cleared. This means that simply catching and ignoring them will result in a thread that usually does not stop :
public void run() {
while (!Thread.getCurrentThread().isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Nothing here
}
}
}
In this example, if the interrupt arrives during the sleep() method (which is 99.9999999999% of the time), it will throw InterruptedException, clear the interrupt flag, then the loop will continue since the interrupt flag is false, and the thread will not stop.
That's why if you implement your "while" correctly, using .isInterrupted, and you really need to catch InterruptedException, and you don't have anything special (like cleanup, return etc..) to do with it, least that you can do is set the interrupt flag again.
The problem in the code you posted is that the "while" relies solely on mExited to decide when to stop, and not ALSO on isInterrupted.
while (!mExited && !Thread.getCurrentThread().isInterrupted()) {
Or it could exit when interrupted :
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return; // supposing there is no cleanup or other stuff to be done
}
Setting the isInterrupted flag back to true is also important if you don't control the Thread. For example, if you are in a runnable which is being executed in a thread pool of some kind, or inside any method anywhere you don't own and control the thread (a simple case : a servlet), you don't know if the interruption is for "you" (in the servlet case, the client closed the connection and the container is trying to stop you to free the thread for other requests) or if it's targeted at the thread (or system) as a whole (the container is shutting down, stopping everything).
In that situation (which is 99% of the code), if you cannot rethrow the InterruptedException (which is, unfortunately, checked), the only way to propagate up the stack to the thread pool that the thread has been interrupted, is setting the flag back to true before returning.
That way, it will propagate up the stack, eventually generating more InterruptedException's, up to the thread owner (be it the jvm itself, of an Executor, or any other thread pool) that can react properly (reuse the thread, let it die, System.exit(1) ...)
Most of this is covered in chapter 7 of Java Concurrency in Practice, a very good book that I recommend to anyone interested in computer programming in general, not just Java, cause the problems and the solutions are similar in many other environments, and explanations are very well written.
Why Sun decided to make InterruptedException checked, when most documentation suggests to rethrow it mercilessly, and why they decided to clear the interrupted flag when throwing that exception, when the proper thing to do is setting it to true again most of the time, remains open for debate.
However, if .wait releases the lock BEFORE checking for the interrupt flag, it open a small door from another thread to modify the mExited boolean. Unfortunately the wait() method is native, so source of that specific JVM should be inspected. This does not change the fact that the code you posted is coded poorly.
I need a thread to wait until a file is exist or created.
I have the following code so far:
while(!receivedDataFile.isFileExists("receiveddata.txt"))
{
try {
Thead.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
When I run it, the following exception appears, and the thread ends:
java.lang.InterruptedException: sleep interrupted
A thread is interrupted when it is blocking (the call to sleep) and another thread calls its interrupt method. The call to interrupt must be made explicitly for this to happen.
Seems that repeating the check for the file would be the logical thing to do if the thread is interrupted, but without knowing the cause of the interruption it's hard to say.
As usual, when it comes to threading, Brian Goetz has something to say on the matter of InterruptedException:
http://www-128.ibm.com/developerworks/java/library/j-jtp05236.html
I must agree Bombes comment: threads don't get interrupted on their own. Contrary to Jokis comment - they're not interrupted when a thread context swap takes place either (in fact, if a thread sleeps, it will surrender it's quantum to any thread that has work to do, but I digress).
Furthermore, I would advise an alternative means of communication than polling for files. You cannot be certain, for example, that once you have spotted a file, that it has been completely written without extra work from the file-writer (such as renaming it when ready, or creating a 'ready' file).
Consider using something more 'data push' such as RMI, HTTP-POST, JMS queues, etc.
You should find out which thread interrupts that thread. Threads don’t do that on their own.
If all you want is a notification when a file is created, AND you can (and willing) to go native (JNI) AND you want only win32 support, you could use the code here.
Well, if you don't know what InterruptedException is and/or don't want to do anything about it, obviously you should at least do something besides returning and exiting your loop. Take out the return, and then you'll keep waiting.
But I'd check into why you're getting interrupted. Something is trying to cancel your thread.