Performing a task every 3 hours.

Discussion in 'Plugin Development' started by damo1995, Feb 12, 2012.

Thread Status:
Not open for further replies.
  1. Hello all,

    Im wondering what would be the best way of performing a task every 3 hours in bukkit?

    I've read about scheduled tasks but my problem is what if the server lags? Would it effect it?

    and if so how would i go about setting it up?

    Please do bare in mind i am still quite new to java so please be paitent with me.

    Thank you.
  2. Offline


  3. Offline


    If the Server lags it just expands the time a little bit.
    A complete lagfree server should perform 20 Ticks per Second. So, your 3 hours would be 72000 Ticks. If your server runs an average Tickrate of 19 Ticks per second because of overload. Your 3 hours would expand to 3 hours and 9 minutes.
  4. I belive the scheduler also supports separate thread tasks that don't get affected by the lag... the ASync methods to be exact.
    However, most methods server aren't thread safe, verry few of them are (see the wiki which), so using non-thread-safe methods in a thread could result in unexplained errors.

    So, what are you going to do in that task ?
  5. Hopefully perform a random number generation sfter throwing a set of keys into a array and using the random number in the key range which will pull the correct price from the same file then setting them to a variable.

    Well that's the plan anyway
  6. Offline


    The easiest solution would be to use a recurring task coupled with a system time check. Use something like this...
    static long timeRef = 0;
    getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){ public void run(){
         if(System.currentTimeMillis() > ((time interval in seconds) * 1000) + timeRef){
              timeRef = System.currentTimeMillis();
    } }, 0, 20);
    AlbireoX likes this.
  7. Offline


    You could also use a Thread:
    1. Thread scheduler = new Thread(new Runnable() {
    2. @Override
    3. public void run() {
    4. while (Thread.currentThread() == scheduler) {// set scheduler to null to stop this thread
    5. final long delay = 3*60*60*1000; // 3 hours
    6. final long endTime = System.currentTimeMillis() + delay;
    7. while (endTime > System.currentTimeMillis()) {// needed in case of spurious wakeups
    8. try {
    9. Thread.sleep(endTime - System.currentTimeMillis() + 1);
    10. } catch (InterruptedException e) {}
    11. }
    13. // code put here will be repeated every 3 hours
    15. }
    16. }
    17. });
  8. Njol
    Isn't that the same as getScheduler().scheduleAsyncRepatingTask() ?
  9. Offline


    I don't think so, because it uses real time and not MC ticks. I think an async task is the same as a sync task, except that the execution takes place in a separate thread.
  10. I could not get amoebaman's version working. it just complaned about N needing to be positive. I also tried Njol's version and again i couldent get this working. It just complaned about something i cannot remember. if somebody could write me an example of this where it actuly works i would be verry greatfull. Thank you.
  11. Offline


    Digi it is a nice method, but unfortunately sleep is unreliable. Anyone (including the OS) can call the interrupt() on your thread, causing the sleep to be exited, which may cause the code to be run more often than 3 hours.

    However, you could combine the two: check every minute (60000 msecs) if 3 hours have passed, and if so, perform the code.

    If you need it to be synchronized (run on main thread); the bukkit.scheduleSync...Task is synchronized - you can start a new task from another thread.

    And avoid the 'scheduleAsync..Task' at all costs; I stopped using it ever since it started throwing severe warnings when reloading.

    See also my helper classes in BKCommonLib:
  12. Offline


    That's why I included this:
    1. while (endTime > System.currentTimeMillis()) {// needed in case of spurious wakeups
  13. Offline


    Put this in the class you are going to use the timer in:
    1. private class Task extends Thread
    2. {
    3. private int x;
    4. private Task(int hours)
    5. {
    6. x = hours;
    7. }
    8. public void run()
    9. {
    10. for(;;)
    11. {
    12. //your code here
    14. try{sleep(60*1000*60*x); //1000 millis * 60 = 60 seconds * 60 = 1 hour * x = your time
    15. }
    16. }
    17. }

    You can only use the timer in the class you made it in, unless you make it public or do this:
    1. public void startTimer(int hours)
    2. {
    3. Task t = new Task(hours);
    4. t.start();
    5. }

    To stop it, just call
    1. t.stop()

    Where t is your timer variable.
Thread Status:
Not open for further replies.

Share This Page