Каково поведение запущенных потоков, запускаемых java.util.Timer при вызове Timer.cancel ()? - PullRequest
2 голосов
/ 09 января 2012

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html

Причина этого вопроса в том, что у меня есть таймер, работающий с интервалом в одну минуту, который выполняет сетевой запрос, который иногда занимает до 5 секунд, и затем записывает в файлна диске.

Когда приложение закрывается, мне нужно очистить обработчики файлов, но я не хочу этого делать, если поток, инициированный таймером, в данный момент заблокирован по сетевому вызову и может попытаться записатьпозже к обработчику закрытых файлов.

Трудно детерминистически проверить, что происходит, когда Timer.stop() вызывается в произвольный момент времени, поэтому я надеюсь, что кто-то, кто либо работает на Java, либо решил аналогичноепроблема может помочь.

Ответы [ 2 ]

2 голосов
/ 09 января 2012

Похоже, что из вашего обновления вы имеете в виду Timer.cancel, который объясняет, что он делает.

/**
 * Terminates this timer, discarding any currently scheduled tasks.
 * Does not interfere with a currently executing task (if it exists).
 * Once a timer has been terminated, its execution thread terminates
 * gracefully, and no more tasks may be scheduled on it.
 *
 * <p>Note that calling this method from within the run method of a
 * timer task that was invoked by this timer absolutely guarantees that
 * the ongoing task execution is the last task execution that will ever
 * be performed by this timer.
 *
 * <p>This method may be called repeatedly; the second and subsequent
 * calls have no effect.
 */
public void cancel() {
    synchronized(queue) {
        thread.newTasksMayBeScheduled = false;
        queue.clear();
        queue.notify();  // In case queue was already empty.
    }
}

Я предполагаю, что вы имеете в виду javax.swing.Timer, поскольку java.util.Timer не имеет остановки () и javax.management.timer.Timer и sun.misc.Timer (имеют методы stop (), но довольно неясны)

AFAIK, очень плохая идея использовать этот таймер для ввода-вывода, поскольку он использует поток GUI и может вызватьон блокируется на периоды времени.

Глядя на код

/**
 * Stops the <code>Timer</code>,
 * causing it to stop sending action events
 * to its listeners.
 *
 * @see #start
 */
public void stop() {
    getLock().lock();
    try {
        cancelEvent();
        timerQueue().removeTimer(this);
    } finally {
        getLock().unlock();
    }
}

Вы можете видеть, что он прекращает посылать новые задачи, но прерывает или останавливает () выполняющие их.

0 голосов
/ 09 января 2012

Используете ли вы Таймер в режиме демона? Пожалуйста, ознакомьтесь с этой документацией, в которой говорится, что такое поток демона.

/**
 * Creates a new timer whose associated thread may be specified to
 * {@linkplain Thread#setDaemon run as a daemon}.
 * A daemon thread is called for if the timer will be used to
 * schedule repeating "maintenance activities", which must be
 * performed as long as the application is running, but should not
 * prolong the lifetime of the application.
 *
 * @param isDaemon true if the associated thread should run as a daemon.
 */
public Timer(boolean isDaemon) {
    this("Timer-" + serialNumber(), isDaemon);
}

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

Что касается закрытия файловых дескрипторов, почему бы вам не сделать это в самом потоке таймера? Если это невозможно сделать, ловушки Shudown - идеальный способ сделать что-то во время закрытия приложения.

Таким образом, вы можете иметь общую блокировку, которая может быть получена таймером для каждого выполнения задачи, и та же самая блокировка может быть получена задачей закрытия для закрытия дескрипторов открытого файла.

Надеюсь, это проясняет ситуацию.

...