You can use a Condition
and wait for the condition to become satisfied in a specified period in a guard thread. The guard thread will receive an InterruptedException
if the condition takes too long.
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
private static class PotentiallyBlockingTask implements Runnable {
private final Lock lock;
private final Condition condition;
public PotentiallyBlockingTask(Lock lock, Condition condition) {
this.lock = Objects.requireNonNull(lock);
this.condition = Objects.requireNonNull(condition);
}
@Override
public void run() {
// run the task
// signal the guard thread that it is done.
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
private static class GuardTask implements Runnable {
private final Lock lock;
private final Condition condition;
public GuardTask(Lock lock, Condition condition) {
this.lock = Objects.requireNonNull(lock);
this.condition = Objects.requireNonNull(condition);
}
public void run() {
lock.lock();
try {
condition.await(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// handle situation
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
PotentiallyBlockingTask pbt = new PotentiallyBlockingTask(lock, condition);
GuardTask gt = new GuardTask(lock, condition);
//....
}
}