ExecutorService中的不确定任务

时间:2019-01-17 06:35:01

标签: java multithreading javafx

我有以下变量:

    private ExecutorService executor;
    private Task<Boolean> worker;

我有一个任务应该在另一个线程中执行,并且应该监视其状态:

    public Worker<Boolean> updateTemplateBuffer() {
    worker = new Task<Boolean>() {
        @Override
        protected Boolean call() throws Exception {
               //task code
    };
    executor.execute(worker);
    return worker; 
}

任务已正确执行,但我无法跟踪任务是否结束。

方法executor.isTerminated()executor.isShutdown()总是在每次通话时false。 告诉我如何正确跟踪任务的状态(开始或完成),因为我以前从未遇到过多线程编程。

3 个答案:

答案 0 :(得分:3)

Task实现具有Worker属性的state接口。您可以收听此属性,并在Worker.State更改为SUCCEEDEDCANCELLEDFAILED时做出反应。

Task<Boolean> task = ...;
task.stateProperty().addListener((obs, oldVal, newVal) -> {
    // Test newVal and do something as needed...
});

或者您可以收听running属性。

task.runningProperty().addListener((obs, oldVal, newVal) -> {
    if (!newVal) {
        // Do something...
    }
});

您还可以在Task上收听WorkerStateEvent

task.setOnSucceeded(event -> {});
task.setOnCancelled(event -> {});
task.setOnFailed(event -> {});

// or even something like
task.addEventHandler(WorkerStateEvent.ANY, event -> {
    // Test event type and do something as needed...
});

然后还有受保护的“状态方法”。

Task<Boolean> task = new Task<>() {

    @Override
    protected Boolean call() throws Exception {
        return false;
    }

    @Override protected void succeeded() {}
    @Override protected void cancelled() {}
    @Override protected void failed() {}

});

所有这些选项都会在 JavaFX Application Thread 上通知您。

答案 1 :(得分:1)

最好在您的completed中使用易失性标志Task,并在执行所有逻辑后将其设置为true

class Task implements Callable<Boolean>{
    private volatile boolean completed = false;
    @Override
    public Boolean call() throws Exception {
        //task code
        completed = true;
    }
    public boolean isCompleted(){
        return this.completed;
    }
}

方法executor.isTerminated(executor.isShutdown()总是返回false,因为您没有关闭执行程序,也不能用来检查各个任务的状态。这些方法将告诉您执行程序的状态。

答案 2 :(得分:0)

在任务类中实现Callable接口。并将任务传递给executorService.Submit(Task);这将返回一个Future实例。调用future.get(),它将等到Call块完成执行