2013-10-10 69 views
0

我試圖更新使用任務preogress吧。這是我的代碼:不能做ObservableList.clear()內螺紋

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();。如果我刪除它,一切都會好的。我無法弄清楚爲什麼會這樣。感謝您的任何提示!

回答

0

由於我不是很熟悉的主題我自己,我發現它爲什麼不是線程安全的在這裏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();