Исполнители Java: как я могу остановить отправленные задачи?

Дважды равняется ==, будет всегда проверять на основе объектных идентификационных данных, независимо от реализации объектов хэш-кода или равняется. Конечно - удостоверяются ссылки на объект, которые Вы сравниваете, volatile (в 1.5 + JVM).

, Если у Вас действительно должен быть исходный объект toString результат (хотя это не лучшее решение для Вашего примера использования в качестве примера), библиотека Lang палаты общин имеет метод ObjectUtils.identityToString (Объект) , который сделает то, что Вы хотите. От JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)

Получает toString, который был бы произведен Объектом, если бы класс не переопределял сам toString. пустой указатель возвратит пустой указатель.

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"

12
задан akf 13 September 2009 в 16:17
поделиться

4 ответа

Тот факт, что вы вызываете cancel () на Future , не означает, что задача остановится автоматически. Вы должны проделать некоторую работу в рамках задачи, чтобы убедиться, что она остановится:

  • Используйте cancel (true) , чтобы прерывание было отправлено задаче.
  • Handle InterruptedException . Если функция в вашей задаче генерирует InterruptedException , убедитесь, что вы корректно завершили работу как можно скорее после перехвата исключения.
  • Периодически проверяйте Thread.currentThread (). IsInterrupted () если задача выполняет непрерывные вычисления.

Например:

class LongTask implements Callable<Double> {
    public Double call() {

         // Sleep for a while; handle InterruptedException appropriately
         try {
             Thread.sleep(10000);
         } catch (InterruptedException ex) {
             System.out.println("Exiting gracefully!");
             return null;
         }


         // Compute for a while; check Thread.isInterrupted() periodically
         double sum = 0.0;
         for (long i = 0; i < 10000000; i++) {
             sum += 10.0
             if (Thread.currentThread().isInterrupted()) {
                 System.out.println("Exiting gracefully");
                 return null;
             }
         }

         return sum;
    } 
}

Кроме того, как упоминалось в других сообщениях: ConcurrentModificationException может быть сгенерировано, даже если используется потокобезопасный класс Vector , потому что итераторы, которые вы получаете из вектора , не являются потокобезопасными и, следовательно, должны быть синхронизированы. В расширенном цикле for используются итераторы, поэтому будьте осторожны:

final Vector<Double> vector = new Vector<Double>();
vector.add(1.0);
vector.add(2.0);

// Not thread safe!  If another thread modifies "vector" during the loop, then
// a ConcurrentModificationException will be thrown.
for (Double num : vector) {
    System.out.println(num);
}

// You can try this as a quick fix, but it might not be what you want:
synchronized (vector) {    // "vector" must be final
    for (Double num : vector) {
        System.out.println(num);
    }
}
24
ответ дан 2 December 2019 в 06:26
поделиться

Исключение ConcurrentModificationException исходит из вашего вызова tasks.clear () , пока ваши Exceutors повторяют ваши задачи Вектор . Что вы можете попробовать сделать, так это вызвать shutdownNow () на вашем ExecutorService

1
ответ дан 2 December 2019 в 06:26
поделиться

Наиболее распространенный случай для ConcurrentModificationException - это когда вектор модифицируется одновременно с итерацией. Часто это делается в одном потоке. Вам необходимо удерживать блокировку вектора на протяжении всей итерации (и осторожно, чтобы не попасть в тупик).

0
ответ дан 2 December 2019 в 06:26
поделиться

fut.get () - это блокирующий вызов, даже по истечении тайм-аута вы будете блокироваться до тех пор, пока задача не будет выполнена. Если вы хотите остановиться как можно ближе к 5-минутной отметке, вам действительно нужно проверить флаг прерывания, я просто рекомендую вам сделать это с помощью метода Thread.isInterrupted (), который сохраняет состояние прерывания. Если вы хотите просто немедленно остановиться и вам не нужно очищать какое-либо состояние, то вызовите исключение, которое будет перехвачено Future и указано вам как ExecutionException.

fut.cancel (true) ничего не делает, как метод invokeAll () уже сделал это за вас.

Если вы не используете коллекцию "tasks" где-то еще, вам, вероятно, не нужно вызывать для нее clear (). Это н' t будет источником вашей проблемы, поскольку метод invokeAll () выполняется со списком к моменту вызова clear (). Но, если вам нужно начать формирование списка новых задач для выполнения, я предлагаю вам сформировать новый Список задач, а не использовать старый Список новых задач.

К сожалению, у меня нет ответа на вашу проблему. Я не вижу здесь достаточно информации, чтобы диагностировать это. Ничто в предоставленном вами фрагменте кода не указывает на неправильное (только ненужное) использование библиотечных классов / методов. Возможно, если вы включили полную трассировку стека вместо ошибки одной строки.

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

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

0
ответ дан 2 December 2019 в 06:26
поделиться
Другие вопросы по тегам:

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