Java计时器会无缘无故停止

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

我是Java新手,如果问题很小,我很抱歉。我的代码可能是一团糟。我在Java中为Raspberry Pi创建了一个在线广播播放器,我必须每10秒做一次POST请求,以检查当前播放的歌曲是什么,如果歌曲发生了变化,我必须做一些事情(如搜索旧歌曲,用新歌曲数据更新显示,将播放会话存储到我的服务器等)。我为此创建了一个类:

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());
}