Как мне создать демон, который выполняет TimerTasks? - PullRequest
1 голос
/ 05 апреля 2020

Мне нужно создать демон в Java, который периодически получает данные через HTTP и сохраняет их в базе данных.

Когда запускается основной поток, он считывает источники данных и интервалы опроса из конфигурации файл и создает TimerTask с соответствующим интервалом для каждого источника данных. Кроме того, он вызывает Runtime.getRuntime().addShutdownHook() для добавления обработчика завершения работы, который выполняет любую очистку, необходимую перед завершением работы. После этого главному потоку больше нечего делать.

Демон предназначен для использования в среде classi c Unix, то есть управляется с помощью скрипта запуска / остановки, хотя он должен быть переносимым на другие ОС (скажем, Windows со SrvAny).

Как бы я go об этом? Если я просто позволю основному потоку завершиться, будут ли экземпляры TimerTask поддерживать работу виртуальной машины, пока все они не будут отменены? Если нет, то как бы я это сделал? 1010 *

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Потоки в Java имеют флаг, указывающий, должны ли они поддерживать JVM или нет. Этот флаг называется «демон»: jvm завершит работу, когда запущены только потоки демона.

Поток, запущенный Timer, по умолчанию не является потоком демона, поэтому он будет поддерживать jvm живым. хотеть. Если вы хотите, чтобы jvm вышел, вы можете создать таймер с помощью new Timer(true) - это установит флаг демона. https://docs.oracle.com/javase/10/docs/api/java/util/Timer.html#% 3Cinit% 3E (булево)

1 голос
/ 05 апреля 2020

Зависит от Timer, на который было запланировано TimerTask: если это Timer было создано , а не для выполнения своих задач в качестве демонов, ожидающий TimerTask будет поддерживать виртуальную машину даже после того, как основной поток закончил свою работу. Это относится ко всем Timer конструкторам, которые не принимают аргумент boolean или где аргумент boolean равен false.

Кажется, что следующее работает как задумано:

package com.example.daemon;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class SampleDaemon {
    private static Timer testTimer = new Timer(false);

    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("Received shutdown request!");
                if (testTimer != null)
                    testTimer.cancel();
                testTimer = null;
            }
        });
        testTimer.schedule(new TestTimerTask(), new Date(), 2000);
    }

    private static class TestTimerTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("Still running…");
        }
    }
}

Он печатает Still running… каждые 2 секунды. Когда JVM получает SIGTERM, программа печатает Received shutdown request! и завершает работу. Это также можно сделать, отправив Ctrl + C с консоли. SIGHUP делает то же самое, что и SIGTERM.

SIGCONT не имеет никакого эффекта; SIGUSR1 приводит к жесткому выходу (предположительно, так же, как SIGKILL), т.е. без выполнения ловушки отключения.

...