2015-09-10 52 views
3

我通过修改可观察数组列表来更新表,但现在2个线程可能会修改可观察数组列表。是否应该将修改列表的代码放入同步方法中,还是只允许1个线程修改列表?在JavaFX中,observableArrayList线程是否安全?

+1

如果修改你的'ObservableList'改变你的'TableView',那么你只能从FX Apllication Thread访问它。 –

+0

http://stackoverflow.com/questions/23344042/modifying-fxcollections-synchronizedobservablelist-out-of-the-ui-thread –

回答

0

你可以通过调用

javafx.collectionsFXCollections.synchronizedObservableList(observableList) 

这为您的observableList您可以使用将项目添加到您的列表的包装创建从ObservableList同步ObservableList。

问题是什么同步对你意味着什么。由于技术同步并不一定意味着它在业务需求方面是同步的,例如,如果必须通过在列表上连续​​调用add(...)两次添加2个项目,并确保它们按顺序包含(中间没有其他项目)。也许你必须确保不同级别的同步。

+0

这个答案中的所有内容都是真实的,但它与真实情况并不相关题。如果'ObservableList'绑定到'TableView',那么你必须*只能从一个线程(FX应用程序线程)访问它。使用同步列表或添加自己的同步时,如果只能从一个线程访问它,那将毫无意义。 –

+1

感谢您的阐述。只通过FX应用程序线程访问'ObservableList'可以通过创建一个'Runnable r'调用'javafx.application.Platform.runLater(r)'来实现。 – michaeak

+0

看到您刚才已经提到'Platform.runLater'这个点。 – michaeak

9

对于这个特殊用例 - 其中ObservableList绑定到TableView,您只能从FX应用程序线程访问列表。这是因为对列表的更改将导致对TableViewall changes to the scene graph must occur on the FX Application Thread的更改。

因此,在这种情况下,ObservableList是否是线程安全的问题是一个有争议的问题:由于您只能因为其他原因从单个线程访问它,因此您并不需要它。

如果您有需要更新列表中的后台线程,您可以通过使用javafx.concurrent API安排这些更新是在呼叫包装他们Platform.runLater(...),或在FX应用程序线程发生(这可能是最好)管理你的线程。

+0

谢谢你阻止我犯大错!我需要使用像这样的私人任务createTableLoaderTask(){ 任务<收藏> tableLoader =新任务<收藏>(){ @覆盖 保护收藏()调用抛出异常{ 回道。retrieveAllJobs(); } }; tableLoader.setOnSucceeded(event - > { Worker worker = event.getSource(); jobData.addAll((Collection )worker.getValue()); }); return tableLoader; } – user2312688

+0

您的'onSucceeded'处理程序可以简化为'event - > jobData.addAll(tableLoader.getValue())',但是,看起来是正确的。 –

+0

格式化效果不佳!我实际上是通过修改后台线程中的列表来修改视图,而不是仅仅检索后台线程中的数据,然后通过调用setOnSucceeded方法更新UI线程上的列表 – user2312688