JavaFX多任务

JavaFX多任务,java,javafx,concurrency,parallel-processing,task,Java,Javafx,Concurrency,Parallel Processing,Task,有人能帮我吗? 我有一个使用JavaFX的程序。 现在按下一个按钮后,我想做n-计算。 这些计算应该使用线程(并行)完成,它们不应该使主JavaFX应用程序挂起/冻结。我想做的是,在计算运行时显示加载状态,如果所有任务都已完成计算,我想继续程序(删除加载状态并显示结果) 在阅读了一些关于“JavaFX中的并发性”的内容后,我想到了以下几点: for (int i = 0; i < n; ++i) { CalcTask task = new CalcTask(i); tas

有人能帮我吗? 我有一个使用JavaFX的程序。 现在按下一个按钮后,我想做n-计算。 这些计算应该使用线程(并行)完成,它们不应该使主JavaFX应用程序挂起/冻结。我想做的是,在计算运行时显示加载状态,如果所有任务都已完成计算,我想继续程序(删除加载状态并显示结果)

在阅读了一些关于“JavaFX中的并发性”的内容后,我想到了以下几点:

for (int i = 0; i < n; ++i) {
    CalcTask task = new CalcTask(i);

    task.setOnSucceeded(e -> {
        // process is just a static method in which I count 
        // how many results (i) I already received 
        // (where n is the required amount). If i == n,
        // I know I am done with all the tasks
        process(task.getValue());
    });

    new Thread(task).start();
}
for(int i=0;i{
//进程只是一个静态方法,我在其中计数
//我已经收到多少结果
//(其中n为所需金额)。如果i==n,
//我知道我已经完成了所有的任务
进程(task.getValue());
});
新线程(任务).start();
}
和CalcTask类:

public class CalcTask extends Task<Integer> {
    protected int id;

    public CalcTask (int id) {
        this.id = id;
    }

    @Override
    public Integer call() {
        return CALCULATION_RESULT;
    }
}
公共类CalcTask扩展任务{
受保护的int-id;
公共计算任务(内部id){
this.id=id;
}
@凌驾
公共整数调用(){
返回计算结果;
}
}

现在我的问题是:这对我来说似乎有点“笨拙”。在JavaFX中有没有更好的方法来实现这样的东西?谢谢:)

既然您扩展了类任务,您还可以覆盖方法
succeed()
并删除主线程上对
任务的调用。setonSucceed()

for (int i = 0; i < n; ++i) {
  CalcTask task = new CalcTask(i);
  new Thread(task).start();
}

public class CalcTask extends Task<Integer> {
    protected int id;

    public CalcTask (int id) {
        this.id = id;
    }

    public void succeeded() {
       process(this.getValue());
    }

    @Override
    public Integer call() {
        return CALCULATION_RESULT;
    }
}

在我看来,更好的方法是RxJavaFx
此示例:
RxJavaFx教程


我想指出的是,你的两个例子并不相同。
Task.successed
方法将在FX线程上调用
process
,而纯
Runnable
方法将在调用
run
的任何线程上调用
process
。谢谢!今天晚些时候我会尝试一下,然后回来评论。好的,谢谢你的回答。我最终实现了它(任务变体)。但我还是有点好奇,是否没有“更干净”的方法来实现这一点。我在考虑一个“容器”,它包含所有任务——如果所有任务都完成了,“容器”将触发一个事件,您可以获取所有任务的结果。但无论如何,谢谢你!嗨-谢谢你的回答,但我不喜欢过度的方法链接。也许对某些人来说,这是一个优雅的解决方案,但不幸的是,对我来说不是。我仍然非常感谢您的贡献:)
public class CalcTask implements Runnable {
    protected int id;

    public CalcTask (int id) {
        this.id = id;
    }

    @Override
    public void run() {
       CALCULATION_RESULT = calculate();
       process(CALCULATION_RESULT);
    }
}
package com.github.pkrysztofiak.rxjavafx.rxjavafxdemo.concurrency;

import java.util.Random;

import io.reactivex.Observable;
import io.reactivex.rxjavafx.observables.JavaFxObservable;
import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
import io.reactivex.schedulers.Schedulers;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class ParallelTasksApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Button button = new Button("Start");
        Label label = new Label();
        HBox hBox = new HBox(button, label);
        stage.setScene(new Scene(hBox));
        stage.show();

        JavaFxObservable.actionEventsOf(button)
        .flatMap(actionEvent -> Observable.range(1, 4))
        .flatMap(i -> Observable.just(i)
                .subscribeOn(Schedulers.newThread())
                .map(this::runLongProcess))
        .observeOn(JavaFxScheduler.platform())
        .scan(0, (aggregator, next) -> ++aggregator)
        .map(String::valueOf)
        .subscribe(label::setText);
    }

    private int runLongProcess(int i) {
        try {
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " i=" + i);
        return i;
    }
}