在线程内部不能做ObservableList.clear()

时间:2013-10-10 16:20:15

标签: multithreading javafx-2

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

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();行上。如果我删除它,一切都会好的。我无法弄清楚为什么会这样。谢谢你的提示!

1 个答案:

答案 0 :(得分:0)

由于我自己并不熟悉Thread,所以我找到了一个更好的解释,为什么它不是线程安全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();