【问题标题】:Indefinite task in ExecutorServiceExecutorService 中的不确定任务
【发布时间】:2019-01-17 06:35:01
【问题描述】:

我有以下变量:

    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 在任何时候调用。 告诉我如何正确跟踪任务的状态(开始或完成),因为我之前从未遇到过多线程编程。

【问题讨论】:

标签: java multithreading javafx


【解决方案1】:

Task 实现了具有state 属性的Worker 接口。当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 上收听WorkerStateEvents。

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 应用程序线程上通知您。

【讨论】:

  • 非常感谢您的详细回复
【解决方案2】:

最好在你的Task 中有一个 volatile 标志completed,并在所有逻辑执行后设置为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,因为您没有关闭执行器并且不能用于检查单个任务的状态。这些方法会告诉你执行者的状态。

【讨论】:

  • 感谢解答,但是不引入额外的flag真的不可能查到任务的状态吗?
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    相关资源
    最近更新 更多