Rescheduling BukkitRunnable throws IllegalStateException

Discussion in 'Spigot Plugin Development' started by finnbon, May 25, 2016.

  1. Hello people!

    In a plugin I'm working on I use BukkitRunnables. For efficiency reasons, I want to cancel the BukkitRunnable at some point, because it doesn't have to do anything. But at a certain point, I also want to restart it, because then it has to time things again. I first call cancel() to cancel the BukkitRunnable. In an event I call runTaskTimer(plugin, 0L, 20L); to start it again, but this throws an IllegalStateException, even through I have already cancelled the task? Is this a limitation from BukkitRunnable, or am I doing something wrong? Here is the stacktrace:

    Thanks in advance.

    - Finn
  2. MiniDigger


    You can't restart a BukkitRunnable afaik.
    If you want to avoid duplicated code, create a new class, extends BukkitRunnable and do your stuff there instead of using a lambda or an anonymous class. Then you can just create a new instance of that class and shedule it.
  3. I already have a class extending BukkitRunnable. I have an 'Arena' class which extends BukkitRunnable, so each arena can manage itself. Shame that we can't restart a BukkitRunnable.

    Is it a waste of resources if I let a BukkitRunnable run every second (20 ticks that is) without executing any code (except for an if-statement)?
  4. MiniDigger


    that depends on your if statement ^^ if you calculate the size of the universe in you if statements that could lead to small performance problems ;)
    If you run a bukkitrunnable without doing anything that is ofcourse a waste.
    But having a bukkitrunnable itself will not use many ressources. If you want to check something that is not true very often you can think about makeing the interval higher but you should be fine.
  5. How can I change the interval without restarting the BukkitRunnable?
    The if statement if simply
    Code (Java):
    if (state == GameState.PLAYING || state == GameState.WAITING) return;
  6. MiniDigger


    you can't ^^
    your problems looks like it could be solved far more effeciently with a custom event.
    Make a GameStateChange event, listen to that can check if the new state is the state you are about. call that event everytime you cange the state and you don't need a runable at all.