Java безлимитный поток останавливается через некоторое время
У меня есть веб-сервер и несколько серверов для хранения данных. Что мне нужно, так это синхронизация между обоими серверами. Веб-серверы всегда работают, и я стараюсь поддерживать работу серверов данных как можно дольше.
Оба имеют базы данных MySQL, и я уже написал сценарии для их синхронизации. Я создал Java-программу, которая получает новые поля данных с веб-сервера и каждые 10 секунд сохраняет их в своей собственной базе данных. Неограниченный поток Java делает это. Это будет фрагмент кода, который делает это:
Timer timer;
Date current_date = new Date() ;
timer = new Timer();
timer.scheduleAtFixedRate(new doCheck(), current_date, 10 * 1000);
Конструктор класса doCheck() извлекает данные с веб-сервера в формате XML. Нет прямого подключения к MySQL через серверы.
Настоящая проблема:
Но когда этот сценарий выполняется 24/7, по истечении определенного периода времени, например, через пару дней, сценарий (в основном поток, извлекающий XML с веб-сервера) неожиданно прекращает работу, и синхронизация полностью отключается.
Возможность № 1: отключение Интернета: я попытался отключить сетевой кабель, и он начал давать исключения, но как только я снова подключил провод, он начал работать совершенно нормально.
Возможность #2: Любое исключение в коде и т. Д. Я веду логи, но в большинстве случаев они внезапно прекращаются без каких-либо исключений или ошибок.
Возможность № 3: Ручная отмена потока: Никто не трогает серверы:P, и есть только одна кнопка, чтобы отменить его, так что это невозможно.
Почему это происходит? Я просто хочу, чтобы этот скрипт запускался неограниченное количество раз.
1 ответ
Я не могу предложить конкретную причину, по которой это могло бы произойти, но у таймера есть только один внутренний поток, и если этот поток умирает, он не перезапускается автоматически. Так что если у вас есть исключение, выброшенное из метода run() объекта TimerTask только один раз, то Timer будет мертв навсегда.
Вы можете пропустить это исключение, поэтому я бы сделал следующее
- Реализуйте обработчик исключений потока по умолчанию и убедитесь, что результат зарегистрирован где-нибудь, где вы можете найти его
- При желании реализуйте блок try / catch / rethrow в вашей реализации TimerTask. Не глотайте исключение здесь, просто зарегистрируйте его и сбросьте (пока, смотрите ниже).
Если из вашей TimerTask выдается исключение, вы должны увидеть его дважды: один раз в попытке / ловле TimerTask и один раз обработчиком исключений по умолчанию, когда поток Timer умирает. Это подтвердит, что поток Timer уничтожается исключением.
Если предположить, что это так, то вам придется посмотреть на исключение и решить, как вы хотите его обработать. Вы можете поймать этот конкретный тип исключения и зарегистрировать / проглотить его (измените реализацию TimerTask в соответствии с требованиями) или, возможно, разрешить исключению распространиться и подать предупреждение в системе.
Возможно, стоит переключиться на использование ScheduledExecutorService, представленного в версии 1.5, поскольку он немного более полезен и МОЖЕТ быть более надежным, если запланированная задача выдает исключение (я не на 100% об этом, проверьте соответствующие документы API для реализации),