@Override
    public void run() {
        synchronized(lock) {
            startTime = java.lang.System.currentTimeMillis() + delay;
        }
        // Loops to act like a timer
        while(true) {
            if(canceled) { return; }
            // Saves all values for use
            synchronized(lock) {
            saveDelay = delay;
            curDelay = delay;
            saveRunning = running;
            saveCanceled = canceled;
        }
        // If timer is ready to run i.e. perform given task
        if(saveRunning) {
            // Make sure we dont start too early
            while(java.lang.System.currentTimeMillis() < startTime) {
                if(saveCanceled) { return; }
                try {
                    thr.sleep(curDelay);
                } catch (Throwable ex) {
                    startTime = java.lang.System.currentTimeMillis() + delay;
                    curDelay = startTime - java.lang.System.currentTimeMillis();
                }
                synchronized(lock) {
                    saveCanceled = canceled;
                }
            }
            synchronized(lock) {
                saveRunning = running;
                saveDelay = delay;
            }
            // Double check stop hasnt been called
            if(saveRunning) {
                r.run();
                startTime += saveDelay; 
            }
        }
        // Wait for someone to call start, but do not busy wait
        else {
            synchronized(lock) {
                try {
                    lock.wait(saveDelay);
                } catch (Exception | Error ex) {
                }
                curDelay = delay;
                startTime = java.lang.System.currentTimeMillis() + delay;
            }
        }
      }
    }