0

我正在尝试使用 Task 更新 preogress 栏。这是我的代码:

ObservableList<somePOJO> listWithProblem = FXCollections.observableArrayList();
Task task = new Task<Void>() {
@Override
public Void call() throws Exception {
    final int max = 10;
    int i = 0;

    while (i < max) {
        if (isCancelled()) {
            break;
        }
        if (i == 0) {
            i++;
            List<SomePOJO> someList = someActionReturningList();
            listWithProblem.clear(); // This list has problem!
            if (!someList.isEmpty()) {
                for (SomePOJO object : someList) {
                    listWithProblem.add(object);
                }
            }
            Thread.sleep(1000);
            updateProgress(i, max);
        } else {
                i++;
                Thread.sleep(1000);
                updateProgress(i, max);
            }
        }
    }
    return null;
}
};

ProgressBar bar = new ProgressBar(0);
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

好像每次都卡在了线上listWithProblem.clear();。如果我删除它,一切都会好起来的。我不明白为什么会这样。感谢您的任何提示!

4

1 回答 1

0

由于我自己对 Thread 不是很熟悉,因此我在这里找到了一个更好的解释来解释为什么它不是 Thread Safe 的Complex concurrency in JavaFX: using ObservableLists and Properties from multiple worker threads

对于代码,我最终更改了以下内容:

ObservableList<somePOJO> listWithProblem = FXCollections.observableArrayList();

// Add a temporary list here
List<SomePOJO> tempList = new Arraylist<SomePOJO> ();

Task task = new Task<Void>() {
    @Override
    public Void call() throws Exception {
        final int max = 10;
        int i = 0;

        while (i < max) {
            if (isCancelled()) {
                break;
            }
            if (i == 0) {
                i++;
                List<SomePOJO> someList = someActionReturningList();

                // It's not good to touch mutable list inside thread: delete it
                // listWithProblem.clear();
                if (!someList.isEmpty()) {
                    for (SomePOJO object : someList) {
                        // Operate on this temporary list for the moment
                        tempList.add(object);
                    }
                }
                Thread.sleep(1000);
                updateProgress(i, max);
            } else {
                i++;
                Thread.sleep(1000);
                updateProgress(i, max);
            }
        }

        // Assign value of temp list to observale list here
        Platform.runLater(new Runnable() {
            public void run() {
                listWithProblem = FXCollections.observableArrayList(tempList);
            }
        });
        return null;
    }
};

ProgressBar bar = new ProgressBar(0);
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
于 2013-10-11T09:06:20.317 回答