If you need to block-and-wait
, as you've described, there is no other option, but have something like awaiCompletion()
implemented.
Your looping approach can be improved. Let's use ThreadPoolExecutor
as an example. It has the following method:
/**
* Blocks until all tasks have completed execution after a shutdown
* request, or the timeout occurs, or the current thread is
* interrupted, whichever happens first.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return {@code true} if this executor terminated and
* {@code false} if the timeout elapsed before termination
* @throws InterruptedException if interrupted while waiting
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
and here is the implementation:
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (;;) {
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}
Please note:
- infinite loop should always have exit condition defined
- in your case timeout is must-have, because it is unlikely you are ready for an endless wait
- naturally you have to know whether it was timeout or job termination
So, here is an adapted version:
public static boolean awaitTermination(JobExecution execution, long timeout) throws InterruptedException {
final long limit = System.currentTimeMillis() + timeout;
for (;;) {
if (null != execution.getExitStatus()) {
return true;
}
if (System.currentTimeMillis() >= limit) {
return false;
}
Thread.sleep(timeout/10);
}
}