Следующая программа демонстрирует проблему (последняя JVM и этажерка):
public static void main(String[] args) throws InterruptedException {
// if this is true, both interrupted and isInterrupted work
final boolean withPrint = false;
// decide whether to use isInterrupted or interrupted.
// if this is true, the program never terminates.
final boolean useIsInterrupted = true;
ExecutorService executor = Executors.newSingleThreadExecutor();
final CountDownLatch latch = new CountDownLatch(1);
Callable<Void> callable = new Callable<Void>() {
@Override
public Void call() throws Exception {
Random random = new Random();
while (true) {
if (withPrint) {
System.out.println(random.nextInt());
System.out.flush();
}
if (useIsInterrupted)
{
if (Thread.currentThread().isInterrupted())
break;
}
else
{
if (Thread.interrupted())
break;
}
}
System.out.println("Nice shutdown");
latch.countDown();
return null;
}
};
System.out.println("Task submitted");
Future<Void> task = executor.submit(callable);
Thread.sleep(100);
task.cancel(true);
latch.await();
System.out.println("Main exited");
executor.shutdown();
}
Это выглядит как известная проблема с многопроцессорными машинами, в основном в 64-битных версиях ОС и java версиях от 1.5 до 7.0
A ОПИСАНИЕ ПРОБЛЕМЫ : При выполнении двух одновременных потоков первый поток прерывает второй, используя Thread.interrupt(). Второй поток проверяет, было ли прервано обращение к методу Thread.isInterrupted(), который всегда возвращает false.
Это происходит на многопроцессорном ПК под управлением 64-битной операционной системы (Vista и Linux). В Vista 64-Bit это происходит при использовании 64-битной JVM (все версии от 1.5 до 1.7), но не происходит при использовании 32-битной JVM. В Linux 64-bit это происходит при использовании 64-битной JVM (все версии от 1.5 до 1.7) или при использовании 32-битной JVM (все версии от 1.5 до 1.7).
Решение заключается в установке версии с исправлением 1.6.0_16-b02 или более поздней версии.
риппер234, я только что запустил это на своей машине и оно всегда останавливается независимо от того, какое значение я использую для отпечатков и какое прерывает их использование. Я использую jdk1.6.0_16. глядя на javadoc, может быть, это как-то связано с тем, что функция interrupted() очищает (прерывается) состояние после каждого вызова и isInterrupted() нет. тот факт, что она работает иногда для jerome, всегда для меня, и никогда(?) для вас может указывать на разницу в jdks, которые мы используем ИЛИ скорость наших машин. если это как-то связано с очищением состояния, то это может объяснить изменчивость.