Search code examples
javamultithreadingshutdownexecutorservice

I Need To Shutdown A ScheduledExecutorService, But Need To Start It Up When Needed


I made a sweet system update feature for this game I'm making here is the code:

public static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private static CountDownThread countDownThread;
public static boolean running = false;

private static short updateSeconds;


public static void start() {
    System.out.println("starting");
    running = true;
    countDownThread = new CountDownThread();
    scheduler.scheduleWithFixedDelay(countDownThread, 0, 1000, TimeUnit.MILLISECONDS);
}

public static void stop() {
    System.out.println("Stoping");
    scheduler.shutdown();
    running = false;
    updateSeconds = 0;
    System.out.println("Stopped");
}

public static void refresh() {
    for (Player p : Static.world.players){ 
        if (p.ready()) {
            if (updateSeconds > 0) {
                ActionSender.sendSystemUpdate(p, updateSeconds+1);
            } else {
                ActionSender.sendSystemUpdate(p, updateSeconds);
            }
        }
    }
}

public static short getUpdateSeconds() {
    return updateSeconds;
}

public static void setUpdateSeconds(short updateSeconds) {
    SystemUpdateHandler.updateSeconds = (short) (updateSeconds);
}

public static class CountDownThread implements Runnable {

    @Override
    public void run() {
        System.out.println(updateSeconds);
        updateSeconds--;
        if (updateSeconds <= 0) {
            Static.server.restart();
            scheduler.shutdown();
            running = false;
        }
    }

}

}

That's so, when the system update counter reaches 0, the server will restart its self. It works fine but here where the problem begins

    case "update":
        if (Short.parseShort(txtSystemUpdate.getText()) != 0) {
            SystemUpdateHandler.setUpdateSeconds(Short.parseShort(txtSystemUpdate.getText()));
            SystemUpdateHandler.refresh();
            if (!SystemUpdateHandler.running) {
                SystemUpdateHandler.start();
            }
        } else {
            SystemUpdateHandler.stop();
            for (Player p : Static.world.players){ 
                if (p.ready()) {
                    ActionSender.sendSystemUpdate(p, 0);
                }
            }
        }
        break;

That is where I call it, basically if I enter a number higher than 0, the program works fine. But I want it so if I enter the number 0, the scheduler will stop running(to save memory) because it not needed unless I send a system update. Basically how do I stop the scheduler from running when I enter 0, but able to starts it back up when I enter a number > then 0(several times).


Solution

  • Once shutdown the ExecutorService can't be started again so move the creation of it from the variable declaration (and remove final) and do that in the start method instead:

    //not static and not final, normal instance variable instead:
    public ScheduledExecutorService scheduler;
    ...
    
    //and create it in the start method isntead:
    public static void start() {
        System.out.println("starting");
        scheduler = Executors.newSingleThreadScheduledExecutor();
        ...