Java计时器会无缘无故停止
我是Java新手,如果问题很小,我很抱歉。我的代码可能是一团糟。我在Java中为Raspberry Pi创建了一个在线广播播放器,我必须每10秒做一次POST请求,以检查当前播放的歌曲是什么,如果歌曲发生了变化,我必须做一些事情(如搜索旧歌曲,用新歌曲数据更新显示,将播放会话存储到我的服务器等)。我为此创建了一个类:Java计时器会无缘无故停止,java,linux,timer,raspberry-pi,schedule,Java,Linux,Timer,Raspberry Pi,Schedule,我是Java新手,如果问题很小,我很抱歉。我的代码可能是一团糟。我在Java中为Raspberry Pi创建了一个在线广播播放器,我必须每10秒做一次POST请求,以检查当前播放的歌曲是什么,如果歌曲发生了变化,我必须做一些事情(如搜索旧歌曲,用新歌曲数据更新显示,将播放会话存储到我的服务器等)。我为此创建了一个类: public class Scrobbler implements Runnable, Commands, Observer { private TimeCounter c
public class Scrobbler implements Runnable, Commands, Observer {
private TimeCounter counter;
private Timer timer;
private Radio radio;
private List<Observer> observers;
private final Object MUTEX= new Object();
private int currentPlaySession;
// And all other variables which I deleted before posting
// Constructor
public Scrobbler(TimeCounter _counter, Radio _radio)
{
currentTrack = null;
counter = _counter;
radio = _radio;
timer = null;
observers = new ArrayList<>();
currentPlaySession = 0;
}
private void GetInfo()
{
// POST request to get current song playing
// If song has changed, notify observers
}
public void Scrobble()
{
// POST request - Scrobble song to my website and last.fm
}
public void StartPlaySession()
{
// Again POST request to my website
}
public void EndPlaySession()
{
// Again POST request to my website
}
@Override
public void start() {
new Thread(this).start();
}
public void stop()
{
timer.cancel();
timer.purge();
timer = null;
}
@Override
public void register(Observer obj) {
if(obj == null) throw new NullPointerException("Null Observer");
synchronized (MUTEX) {
if(!observers.contains(obj)) observers.add(obj);
}
}
@Override
public void unregister(Observer obj) {
synchronized (MUTEX) {
observers.remove(obj);
}
}
@Override
public void notifyObservers(String command) {
for (Observer obj : observers) {
obj.update(command);
}
}
@Override
public void run() {
timer = new Timer();
timer.schedule(new TimeOut(), 0, 10000);
GetInfo();
StartPlaySession();
}
public class TimeOut extends TimerTask
{
@Override
public void run() {
EndPlaySession();
GetInfo();
}
}
@Override
public void update(String command) {
if ("RADIO_STARTED".equals(command))
{
this.start();
}
if ("RADIO_STOPPED".equals(command))
{
this.stop();
if (this.currentTrack != null && this.counter.getTrackTime() >= 60)
this.Scrobble();
EndPlaySession();
}
}
private void handleException(String message)
{
try {
String timeStamp = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("/home/pi/OnlineRadio/error_log.txt", true)));
out.println("(" + timeStamp + ") [SCROBBLER] - " + message + "\n\n\r");
out.close();
} catch (IOException e) {}
this.stop();
this.start();
}
}
但当问题再次出现时,日志文件为空,这意味着甚至没有发生一个异常。我还试图记录所有的数据,每次歌曲的变化,一切都很好,只是停止了一段时间后,没有任何原因。我找不到发生的规律,有时几分钟后就会发生,有时工作几个小时后就会发生
这个应用程序运行在Raspberry Pi模型B上,我不知道这是否意味着什么,但它在JAR中,它以Pi开始(通过cron@reboot),因为我在这个Pi上没有任何监视器,也没有键盘/鼠标,所以这个应用程序必须以它开始,并且一直在后台运行。我使用SSH将JAR传输到Pi并读取日志文件
我在某个地方读到,Java计时器无缘无故停止并不罕见。但是如何解决这个问题呢?为什么要使用计时器并生成线程呢?我生成了一个线程,因为我认为只要计时器在运行(这将冻结我的主线程),它就会处于活动状态,但我错了,注意到线程刚刚启动计时器,但这是一个问题吗?如果需要的话,我可以把线拔掉。至于计时器,为什么不呢?每10秒调用一个方法是否有更好的解决方案?可能是死锁吗?或者服务器没有响应而客户端一直在等待?也许,我甚至没有想到会发生类似的事情,我认为如果服务器没有响应,它会抛出异常。此外,这些天我的互联网连接有问题,所以很有可能,但是如何消除这个问题呢?我在考虑类似于看门狗的东西,它期望Scrobble实例每隔10秒通知它一次,否则它将重新启动计时器。但这不是一个优雅的解决方案。或者在新线程中运行POST请求以避免计时器死锁?另外,timer.scheduleAtFixedRate可能是一个更好的解决方案吗?PS:当它发生时,它从停止到我注意到的那一刻已经过了20分钟。我不认为服务器在这20分钟内无法响应。互联网连接没有崩溃,因为音乐一直在播放(音乐也是从互联网上传输的在线广播)。
try {
writer.close();
} catch (IOException e) {
this.handleException(e.getMessage());
}