Возможно, это дублированный вопрос Thread.isInterrupted не работает, Thread.interrupted работает. Но поскольку я использую совершенно другой способ вызова Thread.isInterrupted()
и обновился до более новой версии jdk, я просто думаю, что это может вызвать проблему другого рода.
В моей программе три потока (не считая основной).
- поток
sleep
засыпает 10 секунд; - поток
checker
проверяет, не прерывается лиsleep
другим потоком; interrupter
прерывает потокsleep
, пока он запущен.
А вот и моя программа:
package foobar;
public class Foobar {
public static void main(String[] args) throws Exception {
Thread sleep = new Thread(new Sleep());
sleep.start();
Thread checker = new Thread(new InterruptedChecker(sleep));
checker.start();
Thread interrupter = new Thread(new Interrupter(sleep));
interrupter.start();
}
}
class InterruptedChecker implements Runnable {
private final Thread thread;
InterruptedChecker(Thread thread) {
this.thread = thread;
}
@Override
public void run() {
while (true) {
if (thread.isInterrupted()) {
break;
}
}
System.out.println("The thread is interrupted.");
}
}
class Sleep implements Runnable {
@Override
public void run() {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Interrupter implements Runnable {
private final Thread thread;
Interrupter(Thread thread) {
this.thread = thread;
}
@Override
public void run() {
System.out.println("interrupting...");
thread.interrupt();
}
}
Интересно то, что кое-что (довольно много) программа продолжает работать и не выводит сообщение "The thread is interrupted."
, что означает, что sleep.isInterrupted()
возвращает false
, но что-то делает .
Вот java -version
моего компьютера (Ubuntu 13.10 64bit):
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
После того, как я прочитал Thread.isInterrupted не работает, Thread.interrupted работает выше, я попытался скомпилировать свой код в другом машина, использующая более старый jdk, и она сработала.
И вот java -version
машины (Red Hat Enterprise Linux AS, выпуск 4 (Nahant Update 3), 64-разрядная версия):
java version "1.6.0_06"
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
Java HotSpot(TM) 64-Bit Server VM (build 10.0-b22, mixed mode)
Итак, мой вопрос:
- Что-то не так в моей программе?
- Если это не так, имеет ли отношение к этой проблеме многоядерный процессор или 64-битная система?
РЕДАКТИРОВАТЬ
Спасибо за комментарий Питера.
Какую проблему ты пытаешься решить?
Я только что прочитал сообщение как я уже говорил в своем комментарии, где в главе «Не глотайте прерывания» говорится, что,
код выше в стеке вызовов может узнать о прерывании и отреагировать на него, если захочет.
Поэтому я не уверен, действует ли поток checker
в моей программе как то, что он здесь называется, верхний код . Я просто пытаюсь доказать, что пост правильный. Но, похоже, что-то не так.
2 ответа
Флаг прерывания сбрасывается, как только он срабатывает. то есть после того, как sleep () был прерван, флаг сбрасывается в false.
РЕДАКТИРОВАТЬ
Поэтому я не уверен, что поток проверки в моей программе действует как то, что здесь называется, как код выше. Я просто пытаюсь доказать, что пост правильный. Но, похоже, что-то не так.
IMHO нет ничего выше другого потока. Обычно вы имеете в виду примерно следующее.
public static void main(String... ignored) throws InterruptedException, ExecutionException {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(new Runnable() {
@Override
public void run() {
methodA();
}
});
Thread.sleep(1000);
future.cancel(true); // interrupts task.
long start = System.nanoTime();
try {
future.get();
} catch (CancellationException expected) {
// ignored
}
es.shutdown();
es.awaitTermination(1, TimeUnit.MINUTES);
long time = System.nanoTime() - start;
System.out.printf("Time to cancel/shutdown was %.1f milli-seconds%n",
time / 1e6);
}
private static void methodA() { // doesn't throw any checked exception
for (int i = 0; i < 100; i++)
methodB();
}
private static void methodB() {
boolean conditionWhichIsTrue = true;
if (conditionWhichIsTrue)
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
Отпечатки
Time to cancel/shutdown was 1.7 milli-seconds
Однако, если вы проглотите прерывание, закомментировав строку Thread.currentThread().interrupt();
, остановка займет около 50 секунд, потому что вы прервали только один вызов для перехода в спящий режим.
Этот вопрос тоже меня некоторое время беспокоил. После некоторого расследования я получил ответ.
Когда InterruptedChecker
проверяет состояние isInterrupted
, поток Sleep
уже умер. Попробуйте добавить трудоемкий код после Thread.currentThread().interrupt();
в классе Sleep
и повторите попытку.
статус "прервано" для потока сбрасывается, когда этот поток завершается.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].