Давайте подумаем о следующем фрагменте кода, который ведет себя как ожидалось.Поток запускается, затем приостанавливается, затем останавливается и завершает свое выполнение:
public static void main(final String[] args) throws InterruptedException {
Executor exec = Executors.newSingleThreadExecutor();
MyThread thread = new MyThread();
exec.execute(thread);
thread.pause();
thread.pause(); // unpause
}
Теперь давайте добавим немного спящего в поток, чтобы он на некоторое время приостановился:
public static void main(final String[] args) throws InterruptedException {
Executor exec = Executors.newSingleThreadExecutor();
MyThread thread = new MyThread();
exec.execute(thread);
thread.pause();
Thread.sleep(500);
thread.pause(); // unpause
}
Но этот код никогда не заканчивается.Почему?
Вот реализация метода pause, он проверяет закрытое логическое поле на паузу:
public synchronized void pause() {
paused = (paused) ? false : true;
}
А вот реализация переопределенного метода run:
@Override
public void run() {
// don't worry, I just need som dummy data to take some cpu time ;)
PriorityQueue<Double> queue = new PriorityQueue<Double>();
Random random = new Random(System.currentTimeMillis());
System.out.println("I stared");
checkPause();
// let's do some big computation
for (int i=0; i<10000000; i++) { // 10 mio
System.out.println(i);
queue.add(random.nextDouble());
if (i % 3 == 0) {
queue.poll(); // more complex operation
}
}
System.out.println("I'm done");
}
private void checkPause() {
synchronized (this) {
if (paused) {
while (paused != false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Когда я попробую отладить, я остановлюсь на методе wait()
.Тогда это просто ждет: /