I have following class:
public class PawnThread implements Runnable {
public void start() {
thread.start();
}
@Override
public void run() {
try {
while (... some finish condition ...) {
move();
synchronized (this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.err.println(pawn.toString() + ": thread interrupted :(");
}
}
void move() {
... some blocking actions
}
synchronized void suspend() {
suspendFlag = true;
}
synchronized void resume() {
suspendFlag = false;
notify();
}
}
Now I have a list of its objects:
private final List<PawnThread> pawnThreadList;
I defined some helper method to suspend all of them:
public void suspendAll() {
pawnThreadList.forEach(PawnThread::suspend);
}
Now suspend()
method is only about changing flag. The requirement is, that when I leave suspendAll()
method, all threads should be actually paused (they cannot be in RUNNABLE
state) - for now it is not a case, beacause for some of them, it may take some time to actually finish their job before pause.
I would be grateful for advice what is correct design for this soulution.
Regards
Make PawnThread#suspend()
wait for suspension to be completed:
public class PawnThread implements Runnable {
private final Waiter suspender = new Waiter();
private final Waiter suspending = new Waiter();
@Override
public void run() {
try {
while (...) {
suspending.suspend();
move();
suspending.resume();
suspender.await();
}
} catch (InterruptedException e) {
...
}
}
void suspend() throws InterruptedException {
suspender.suspend();
suspending.await();
}
void resume() {
suspender.resume();
}
}
public class Waiter {
private boolean waiting;
public synchronized void await() throws InterruptedException {
while (waiting) {
wait();
}
}
public synchronized void suspend() {
waiting = true;
}
public synchronized void resume() {
waiting = false;
notify();
}
}