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 ではない理由のより良い説明を見つけますJavaFX の複雑な並行性: 複数のワーカー スレッドからの ObservableLists とプロパティの使用

コードについては、最終的に次のことを変更しました。

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 に答える