Java任务setOnSucceded不起作用

时间:2018-03-28 08:09:05

标签: java task executorservice

我有一个问题,类似于此,它不起作用。那么Task运行正常,但'setOnSucceeded'或'setOnFailed'永远不会运行。我使用'ExecutorService'。此外,程序永远不会完成,它只是继续运行。我试着用'new Thread(task).start();'然后它很成功,但是'setOnSucceeded'也没有开火。

package stackoverflow;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;

public class X {

    private ExecutorService exec;

    public X() {
        exec = Executors.newCachedThreadPool();
        run();
    }

    public static void main(String[] args) {
        X x = new X();
    }

    private void run() {
        Task<Void> task = new Task<Void>() {
            @Override
            public void run() {
                System.out.println("In Task");
                this.succeeded();
            }

            @Override
            protected Void call() throws Exception {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
        };

        task.setOnSucceeded((WorkerStateEvent event) -> {
            System.out.println("In set on Succeded");
        });

        task.setOnFailed((WorkerStateEvent event) -> {
            System.out.println("In Failed");
        });

        exec.execute(task);
    }

}

1 个答案:

答案 0 :(得分:1)

JavaFX实用程序类的重点是JavaFX负责线程等。因此,您无需创建任何ExecutorServiceThread或其他内容。另一方面,您需要启动Application,然后创建Service,以创建Task

此外,您不需要覆盖run(),因为JavaFX已经实现了它。逻辑运行的方法是call()。因此,在所有这个mambo-jambo之后,JavaFX将为您创建succeeded()方法。不要手动调用它,因为这只会引起混淆。另一方面,您可以覆盖它,因此您可以为succeeded() hook添加另一个选项。

所以,这是代码:

package stackoverflow;

import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.stage.Stage;

// extending Application
public class X extends Application {

    // Empty constructor. I just put it here so we know explicitly that a no-arg construcor exists.
    public X() {
        // NOP
    }

    @Override
    // a hook for starting the Applicatoin
    public void start(Stage primaryStage) {
        run();
    }

    // This is a proper entry point of a JavaFX application
    public static void main(String[] args) {
        launch(args);
    }

    private void run() {
        // creating a service, then running it
        ExampleService service = new ExampleService();
        service.start();
    }

    // this is the dummy service
    private static class ExampleService extends Service<Void> {

        @Override
        protected Task<Void> createTask() {
            Task<Void> task = new Task<Void>() {

                @Override
                protected Void call() throws Exception {
                    System.out.println("called");
                    // for Task<Void> we should return null
                    return null;
                }

                @Override
                protected void succeeded() {
                    // one hook - overriding
                    super.succeeded();
                    System.out.println("Succeded");
                }

                @Override
                protected void failed() {
                    // one hook - overriding
                    super.failed();
                    System.out.println("Failed");
                }
            };

            task.setOnSucceeded((WorkerStateEvent event) -> {
                // another hook - callback lambda
                System.out.println("In set on Succeded");
            });

            task.setOnFailed((WorkerStateEvent event) -> {
                // another hook - callback lambda
                System.out.println("In Failed");
            });
            return task;
        }

    }

}

更新

我更改了start()call()方法,看看发生了什么:

@Override
public void start(Stage primaryStage) {
    System.out.println("--> in start: " + Thread.currentThread().getName());
    Thread.dumpStack();
    run();
}


            @Override
            protected Void call() throws Exception {
                System.out.println("called in thread: " + Thread.currentThread().getName());
                Thread.dumpStack();
                return null;
            }

start()通过某种JavaFX Application Thread调用InvokeLaterDispatcher

call()的{​​{1}}调用Thread-4方法。 JavaFX似乎在异步任务方面设计得非常好。在Swing中,我们必须维护我们的线程池。在JavaFX中我们不需要,除非我们特别需要JavaFX无法处理。我发现这可能,但不太可能。