Почему Java Future.get (timeout) не надежен?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
26
задан Andrew Raphael 3 December 2010 в 23:46
поделиться

3 ответа

Нет никаких оснований ожидать, что тест пройдёт. Учитывая, что вы отправляете задание на выполнение, а затем ждете его завершения, может пройти любое количество времени, прежде чем начнется ваше ожидание Future#get(), что даст заданию достаточно времени, чтобы исчерпать продолжительность сна и завершить его.

В вашем случае мы можем предположить, что поток, работающий в пределах Executor, получает фокус, в то время как ваш основной поток, проходящий через test(), находится в режиме ожидания, несмотря на то, что находится в рабочем состоянии. Что касается наблюдаемой разницы между остановкой отправленной задачи на две и три секунды, я ожидаю, что вы можете найти ситуации, когда даже трех секунд недостаточно, в зависимости от того, какие другие процессы заняты на вашем компьютере.

15
ответ дан seh 3 December 2010 в 23:46
поделиться

@seh прав.

Вы ожидаете от Java того, что обычно называют «поведением в реальном времени». Этого невозможно достичь надежно, если вы не используете библиотеки реального времени в дистрибутиве Java с поддержкой реального времени, работающем в операционной системе реального времени.

Просто чтобы проиллюстрировать, реализация потоков Java в современных JVM, таких как HotSpot, полагается на собственный планировщик потоков операционной системы хоста, чтобы решить, какие потоки запускать когда. Если планировщик потоков не знает о крайних сроках и прочем в реальном времени, он, скорее всего, примет решение о том, какие потоки запускать и когда выполнять. Если система загружена, любой конкретный поток может не запуститься по расписанию на несколько секунд ... или дольше ... после того, как пройдут условия, которые препятствовали его работе (например, ожидание события таймера).

Тогда есть проблема, что Java GC может заставить все другие потоки блокироваться.

Если вам действительно нужно поведение Java в режиме реального времени, оно доступно. Например:

Тем не менее, вы должны ожидать, что ваши приложения будут использовать другие API для работы в режиме реального времени.

11
ответ дан Stephen C 3 December 2010 в 23:46
поделиться

Я должен сказать, я думаю, что другие два ответа в настоящее время имеют слишком низкое мнение о классах параллелизма Java. Они не дадут вам миллисекундную точность (чего ожидают «реальные» приложения реального времени), но обычно они работают достаточно хорошо. Я написал крупномасштабные коммерческие сервисы с использованием Futures и Executors, и они обычно работали в течение 10 миллисекунд ожидаемого времени, даже под нагрузкой.

Я провел этот тест как на MacOS 10.6 с Java 1.6, так и на WinXP с Java 1.6.0_22, и оба они работают как положено.

Я изменил код следующим образом, чтобы проверить точность:

    long time1 = System.nanoTime();

    System.out.println("Submitting");
    final Future<Object> future = exec.submit(call);
    try {
        future.get(1000, TimeUnit.MILLISECONDS);

        long time2 = System.nanoTime();
        System.out.println("No timeout after " + 
                             (time2-time1)/1000000000.0 + " seconds");

        fail("expected TimeoutException");
    } catch (TimeoutException ignore) {
        long time2 = System.nanoTime();
        System.out.println("Timed out after " +
                             (time2-time1)/1000000000.0 + " seconds");
    }
    finally {
        exec.shutdown();
    }

В XP это печатает «по истечении 1,002598934 секунд», а в MacOS X печатает «по истечении 1,003158 секунд». ]

Если бы оригинальный постер описывал их ОС и версию JDK, возможно, мы могли бы определить, является ли это конкретной ошибкой.

7
ответ дан andrewmu 3 December 2010 в 23:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: