Java 无限线程在一段时间后停止

4
我有一个Web服务器和一些数据存储服务器。我需要的是这两个服务器之间的同步。Web服务器始终保持开启,我尽量让数据服务器保持开启。
它们都有MySQL数据库,并且我已经编写了脚本来将它们同步。我制作了一个Java程序,每10秒从Web服务器获取新的数据字段并将其存储在自己的数据库中。一个无限的Java线程会执行此操作。以下是执行此操作的代码片段:
Timer timer;
Date current_date = new Date() ;
    timer = new Timer();
    timer.scheduleAtFixedRate(new doCheck(), current_date, 10 * 1000);

该类的构造函数doCheck()从Web服务器以XML格式获取数据。服务器之间没有直接的mysql连接。
真正的问题是:但是,当此脚本运行24/7后,经过一定时间(例如几天),脚本(基本上是从Web服务器获取XML的线程)突然停止运行,并且同步完全断开。
可能性#1:互联网断开连接:我尝试拔掉网络电缆,它开始出现异常,但只要我重新连接电缆,它就可以正常工作。
可能性#2:代码中的任何异常等:我正在维护日志,但大多数时候它会突然停止而没有任何异常或错误。
可能性#3:手动取消线程:没有人触摸服务器:P,只有一个按钮可以取消它,因此这不可能发生。
为什么会发生这种情况?我只想让这个脚本无限次运行。

假设您的意思是doCheck()的run()方法执行操作,而不是它的构造函数? - Affe
1个回答

8
我无法确切地说明为什么会发生这种情况,但计时器只有一个内部线程,如果此线程死亡,则不会自动重新启动。因此,如果您的TimerTask的run()方法抛出异常一次,那么计时器将永远死亡。
您可能会错过此异常,因此建议执行以下操作:
- 实现默认线程异常处理程序,并确保在可以找到的某个位置记录结果。 - 在您的TimerTask实现中可选地实现try/catch/rethrow块。不要在此处吞下异常,只需记录并重新抛出它(暂时如此,请参见下文)。
如果您的TimerTask中有异常被抛出,您应该会看到两次,一次是在TimerTask的try/catch中,一次是当Timer线程死亡时由默认异常处理程序抛出。这将确认异常导致了计时器线程的终止。
假设是这种情况,那么您需要查看异常并决定如何处理它。您可以捕获特定的异常类型并记录/忽略它(修改您的TimerTask实现以适应),或者让异常传播并在系统中引发警报。也许值得考虑使用1.5中引入的ScheduledExecutorService,因为它更有用,如果计划任务抛出异常,则可能更加稳健(我不是100%确定,请检查相关的API文档以获取实现)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接