I have a long runnable. It performs a large number of iterations inside the while loop in its run () function. I need functionality to pause and resume runnable, which I implemented with volatile Boolean pauseFlag, which can be set by another thread.
Once Runnable has detected that pauseFlag- true, it calls pauseFlag.wait()to pause its execution. Resume is done by setting pauseFlagto false, and then calling pauseFlag.notifyAll().
Thus, it pauseFlagacts as a flag and mutex. However, this combined functionality does not work. Runnable retains the lock pauseFlag.wait()indefinitely.
If I create a separate mutex, say, Object mutex = new Object();and use mutex.notifyAll()/ mutex.wait(), but when used pauseFlagas a boolean flag, Runnable behaves as intended.
The non-working code is shown below:
public class PausableRunnable implements Runnable
{
private boolean done;
private volatile Boolean pauseFlag = false;
public void pause()
{
pauseFlag = true;
}
public void resume()
{
pauseFlag = false;
synchronized (pauseFlag)
{
pauseFlag.notifyAll();
}
}
@Override
public void run()
{
try
{
while (!done && !Thread.currentThread().isInterrupted())
{
while (pauseFlag)
{
synchronized (pauseFlag)
{
pauseFlag.wait();
}
}
}
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
So, although I found a solution using a separate object, I would like to understand the problem. Why does this implementation fail?
source
share