Application start and stop functions with multithreading support

Viewed 52

I have an application that should be able to:

Start:

  • only by clicking "Start" button

Stop:

  • clicking "Stop" button
  • clicking "X" button
  • when all jobs are done (basically Application.stop() method invoked from non-javafx thread)

All of the thing should happen "gracefully".

Buttons code:

@FXML
private void start() {
    Application.start();
}

@FXML
private void stop() {
    Application.stop();
}

And the main Application start() and stop() functions (whole Application class):

public class Application {

    private static final AtomicBoolean isStarted = new AtomicBoolean(false),
            startPending = new AtomicBoolean(false),
            stopPending = new AtomicBoolean(false);

    private static final Object lock = new Object();

    //------Functionals below

    public static synchronized void start() {
        if(isStarted.get()) {
            Gui.showError("Application is already started");
            return;
        } else if(startPending.get() || stopPending.get()) return;
        isStarted.set(true);
        startPending.set(true);
        new Thread(startInternals()).start();
    }

    private static Runnable startInternals() {
        return () -> {
            synchronized(lock) {

                //do something

                Logger.print("Started");
                startPending.set(false);
            }
        };
    }

    public static synchronized void stop() {
        if(!isStarted.get()) {
            Gui.showError("Application is not started");
            return;
        } else if(stopPending.get()) return;
        isStarted.set(false);
        stopPending.set(true);
        new Thread(stopInternals()).start();
    }

    private static Runnable stopInternals() {
        return () -> {
            synchronized(lock) {

                //do something

                Logger.print("Stopped");
                stopPending.set(false);
            }
        };
    }

    //------Notes below

    /*
    ===RULES===
    --START:
    STARTED -> NO
    STOPPED -> YES
    STARTING -> NO
    STOPPING -> NO
    --STOP:
    STARTED -> YES
    STOPPED -> NO
    STARTING -> YES
    STOPPING -> NO
    */

}

Is this approach fully correct? Is there any way I could do it better/easier?

PS. I've added "stop" ability when starting in case of "X" clicking (the app should terminate gracefully". Take a look at the bottom of the file for notes.

0 Answers
Related