I'm implementing the following Java interface to allow threads to be paused and resumed. I've a working version that uses wait()/notifyAll(), but I wondered if there was an easier way to do it (say, using some nifty widget in java.util.concurrent)?
public interface Suspender {
/**
* Go into pause mode: any threads which subsequently call maybePause()
* will block. Calling pause() if already in pause mode has no effect.
*/
void pause();
/**
* Leave pause mode: any threads which call maybePause() will not block,
* and any currently paused threads will be unblocked. Calling resume()
* if not in pause mode has no effect.
*/
void resume();
/**
* If the Suspender is in pause mode, block, and only resume execution
* when the Suspender is resumed. Otherwise, do nothing.
*/
void maybePause();
}
Yes there is, but via architecture.
So what it does is to basically schedule and cancel the runnable based on your pause/resume calls.
Obviously that does not pause a thread mid-task, and this is a good thing, because if you could pause a thread during execution, it could potentially cause all kinds of issues. This starts with unreleased locks, but also includes half-open network connections, half-written files and so on.
So whenever you have a thread that has a single task, do not pause it. Only if you have a thread that does a repeated task (hence the ScheduledExecutorService), you can skip further invocations of that task. Your thread can then internally decide whether or not it can pause at this very moment by querying the
Thread.interrupted()
flag during code states where a pause/cancel would be reasonably possible.