如何使用线程池在非GUI线程中运行任务

时间:2019-04-22 13:11:24

标签: java multithreading task

我正在同时计算三个不同的值,这取决于我的应用程序的级别状态,因此我使用Tasks进行了更快的计算。但是,如果我想在计算过程中更改级别,那是不可能的,因为在计算过程中所有按钮都被禁用了。

我发现我无法取消任务,因为我的GUI冻结,直到任务完成为止。因此我无法取消任务,因为它们已经完成

我的GUI有此buttonclick事件

buttonIncreaseLevel.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        increaseLevelButtonActionPerformed(event);
                    }
                });

            }
        });

它会增加一个级别并启动此方法

        createTask(taskLeftEdge,EdgeType.LEFT);
        createTask(taskBottomEdge,EdgeType.BOTTOM);
        createTask(taskRightEdge,EdgeType.RIGHT);

        pool.submit(taskRightEdge);
        pool.submit(taskBottomEdge);
        pool.submit(taskLeftEdge);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("[Future] Started to wait for task (future)");
                    // A task is also its own future
                    ArrayList taskR = (ArrayList) taskRightEdge.get();
                    ArrayList taskB = (ArrayList) taskBottomEdge.get();
                    ArrayList taskL = (ArrayList) taskLeftEdge.get();

                    System.out.println("[Future] " + taskR);
                    System.out.println("[Future] " + taskB);
                    System.out.println("[Future] " + taskL);
                } catch (InterruptedException | ExecutionException ex) {
                    Logger.getLogger(FUN3KochFractalFX.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        ).start();

创建任务的方法

    private void createTask(Task task, EdgeType type){
        if (task != null) {
            application.cancelProgress(type);
            task.cancel();
        }
        // There's a new task that performs some work
        switch(type){
            case LEFT:
                taskLeftEdge = new EdgeGeneratorTask("Task: " + taskNumber, type, this, application);
                task = taskLeftEdge;
                edges.addAll(koch.generateLeftEdge());
                break;
            case BOTTOM:
                taskBottomEdge = new EdgeGeneratorTask("Task: " + taskNumber, type, this, application);
                task = taskBottomEdge;
                edges.addAll(koch.generateBottomEdge());
                break;
            case RIGHT:
                taskRightEdge = new EdgeGeneratorTask("Task: " + taskNumber, type, this, application);
                task = taskRightEdge;
                edges.addAll(koch.generateRightEdge());
                break;
        }
        taskNumber++;

        application.setProgress( task, type);
    }

还有任务本身。 Kochfractal类是进行计算的地方

    private static final Logger LOG = Logger.getLogger(EdgeGeneratorTask.class.getName());
    private final String id;
    private EdgeType type;
    private KochFractal calc;
    private FUN3KochFractalFX application;


    public EdgeGeneratorTask(String id, EdgeType type, KochManager manager, FUN3KochFractalFX main) {
        this.id = id;
        this.type = type;
        calc = new KochFractal(manager);
        application = main;
    }

    @Override
    protected ArrayList<Edge> call() throws Exception {
        ArrayList<Edge> edges = new ArrayList<>();
        switch(type){
            case LEFT:
                edges = calc.generateLeftEdge();
                break;
            case BOTTOM:
                edges = calc.generateBottomEdge();
                break;
            case RIGHT:
                edges = calc.generateRightEdge();
                break;
        }

        int MAX = edges.size();
        for (int i = 1; i <= MAX; i++) {
            if (isCancelled()) {
                break;
            }
            updateProgress(i, MAX);
            updateMessage(id + " " + i);
        }
        return edges;
    }

我希望通过在JavaFX GUI上执行操作来取消这些线程。 这些线程应在后台线程而不是GUI线程本身上运行

0 个答案:

没有答案