Indefinite task in ExecutorService

问题: I have the following variables: private ExecutorService executor; private Task<Boolean> worker; I have a task that should be performed in another thread...

问题:

I have the following variables:

    private ExecutorService executor;
    private Task<Boolean> worker;

I have a task that should be performed in another thread and the state of which should be monitored:

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

The task is executed correctly, but I can’t track whether the task has ended or not.

Methods executor.isTerminated() and executor.isShutdown() always false anytime of a call. Tell me how to track the state of the task correctly (started or completed), because I had never encountered multi-threaded programming before.


回答1:

Task implements the Worker interface which has the state property. You can listen to this property and react when the Worker.State changes to SUCCEEDED, CANCELLED, or FAILED.

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

Or you could listen to the running property.

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

You can also listen for WorkerStateEvents on the Task.

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...
});

Then there's also the protected "state methods".

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() {}

});

All these options will notify you on the JavaFX Application Thread.


回答2:

It is better to have a volatile flag completed in your Task and set to true once the all the logic is executed.

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;
    }
}

The methods executor.isTerminated() and executor.isShutdown() always returns false as you did not shutdown the executor and cannot be used to check the status of individual tasks. These methods will tell you the state of the executor.


回答3:

Implement the Callable interface in the Task Class. And pass the Task to the executorService.Submit(Task); which will return a Future instance. Call future.get() which will wait until the Call block has completed execution

  • 发表于 2019-01-18 18:54
  • 阅读 ( 212 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除