Java 支持多线程的应用程序启动和停止函数

Java 支持多线程的应用程序启动和停止函数,java,multithreading,javafx,Java,Multithreading,Javafx,我有一个应用程序,应该能够: 开始: 仅通过单击“开始”按钮 停止: 点击“停止”按钮 点击“X”按钮 完成所有作业后(基本上是从非javafx线程调用Application.stop()方法) 所有的事情都应该“优雅地”发生 按钮代码: @FXML private void start() { Application.start(); } @FXML private void stop() { Application.stop(); } 以及主应用程序start()

我有一个应用程序,应该能够:

开始:

  • 仅通过单击“开始”按钮
停止:

  • 点击“停止”按钮
  • 点击“X”按钮
  • 完成所有作业后(基本上是从非javafx线程调用Application.stop()方法)
所有的事情都应该“优雅地”发生

按钮代码:

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

@FXML
private void stop() {
    Application.stop();
}
以及主应用程序start()和stop()函数(整个应用程序类):

这种方法完全正确吗?我有没有办法做得更好/更容易


另外,我在启动时添加了“停止”功能,以防“X”点击(应用程序应正常终止)。请查看文件底部的注释。

注意,您的同步,虽然一开始并不错误(我花了很少的时间进行评估),在某些地方似乎很奇怪。这里有5个不同的对象在进行同步3
AtomicBoolean
s
Application.class
Application.lock
。对于这种任务,这是非常早的。对于
AtomicBoolean
来说,使用
比较数据集
和类似的东西会更好,但因为有似乎不止两个州,使用
AtomicReference
可能是一个好主意。但是,似乎您最好简单地使用
javafx.concurrent.Task
@fabian非常感谢您的想法!您能为您最简单的解决方案创建一个简单的草图并发布在pastebin.com上吗?这真的会很有用让我明白你的想法
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
    */

}