Проблема вашего кода в том, что вы хотите отменить / остановить ваши рабочие потоки с помощью метода interupt (), но в то же время вы вызываете методы в потоке, которые будут генерировать прерванное исключение, если поток уже прерван, иэто очистит статус прерывания.
Так, например, что может произойти в вашем коде:
ваш цикл метода запуска эльфа:
while (threadIsAlive()) {
1) //dostuff -> while you are doing the stuff, supervisor call threadGroup.interrupt()
2) awaitRandom();
}
1) во время вашего doStuffкод, супервизор вызывает threadGroup.interrupt () , это установит статус прерывания в вашем потоке, и если вы вызовите Thread.currentThread.isInterrupted (), вы получите true
2) здесь вывызывают метод sleep (), метод sleep будет выдавать InterruptedException , если он вызван в уже прерванном потоке, и он очистит состояние прерывания!проверьте javadoc: https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep(long), поэтому, если вы вызываете threadIsAlive () , метод Thread.currentThread.isInterrupted () вернет false.
Так чтовы можете сделать это, вы можете перехватить interrputedException в методе awaitRandom () (и во всех других методах, которые выдают InterruptedExceptions и очистить статус прерывания) и снова установить статус прерывания следующим образом:
try {
Thread.sleep(waitingTime);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); //restores the interrupt status
}
Но гораздо лучшеопция заключается в том, чтобы отменить / остановить потоки с помощью другого механизма, отличного от флага прерывания.Вы можете ввести некоторую новую переменную остановки флага volatile в вашем рабочем потоке (аналогично тому, как это делается с goalNotAchtained), и вы можете установить эту переменную, если хотите отменить / остановить поток.