簡體   English   中英

Javafx:javafx.concurent和Platform.runLater之間的區別?

[英]Javafx: Difference between javafx.concurent and Platform.runLater?

對於多線程JavaFx編程的javafx.concurent和Platform.runLater之間到底有什么區別,我很好奇。

這是否意味着使用javafx.concurrent,我們可以有多個實際的繪圖線程,還是全部都結束在一個線程上?

例如,我喜歡的一件事是使用JavafX並同時擺動,因為它們都使用了2個不同的繪圖線程。 我會為較重的內容使用swing(例如,打開FileChooser),而對核心視覺內容使用JavaFX(例如,播放無縫的循環視頻)。 但是,由於該無頭異常錯誤,mac使其無法實現,因此一切都落在javafx上,這意味着在執行諸如打開文件選擇器之類的操作時會出現很多暫停。

如果我使用javafx.concurrent重寫我的應用程序,我是否可以像以前使用Swing + JavaFX一樣模仿2個繪制線程的經驗?

Platform.runLater

WorkerPlatform.runLater補充。

  • 當您從JavaFX應用程序線程中執行時,並且要在JavaFX應用程序線程上運行一些邏輯時,請使用Platform.runLater
  • 當您在JavaFX Application Thread上運行並且想要在新線程上生成一些邏輯或(特別是)I / O時,請使用Worker ,以便不阻塞JavaFX Application Thread。

您永遠不會希望在Platform.runLaterrun方法中執行網絡I / O,但通常希望在Workercall方法中進行網絡I / O。

任務與服務

考慮使用WorkerTaskService子類。 這些是FutureTask的 JavaFX包裝器(后者又是Runnable )。 工作者提供了一種在后台線程上運行邏輯的調用方法。 它們維護執行狀態 (通過向JavaFX線程提供線程安全的回調通知來更改狀態),並通過valuemessageexception屬性返回調用結果。

利用Task and Service javadoc示例中的設計模式來簡化具有以下功能的線程安全應用程序的創建:

  • 異步獲取數據以更新UI。
  • 定期更新消息以了解任務進度。
  • 構造尚未附加到顯示場景的節點圖。
  • 通過進度條等監視進度

一起使用Workers和Platform.runLater

另外,使用TaskService與使用Platform.runLater不兼容。 例如,如果您有一個運行時間非常長的Task ,您希望從中定期將部分結果返回到UI或在緩沖區填充時返回,則可以在任務的call方法中執行Platform.runLater

使用現有的線程系統

當您沒有庫提供的現有線程服務,而是創建自己的線程以在后台執行時,工作器將非常有用。 如果您具有現有的線程服務,則需要使用Platform.runLater在JavaFX應用程序線程上執行邏輯。

小心編寫多線程代碼

請注意,即使您使用Worker ,您仍然需要知道您在做什么。 您仍然必須注意不要違反標准JavaFX並發規則,例如從不更新活動場景圖中的節點(包括不更新活動場景圖中的節點綁定到的值),例如可觀察到的項目支持列表ListView )。

回答您的一些其他問題

這是否意味着使用javafx.concurrent,我們可以有多個實際的繪圖線程,還是全部都結束在一個線程上?

JavaFX中只有一個渲染線程。 您不能使用JavaFX並發創建更多渲染線程。 您可以執行一些操作,例如在JavaFX線程之外創建節點,或者使用許多線程將像素設置為屏幕外的WriteableImage或Canvas,但是最終每個渲染操作都將通過JavaFX系統管理的單個線程,您無法對其進行控制。

如果我使用javafx.concurrent重寫我的應用程序,我是否可以像以前使用Swing + JavaFX一樣模仿2個繪制線程的經驗?

不。即使您可以,我也不建議這樣做。 使用這樣的模型,創建微妙的,難以調試的線程處理相關錯誤太容易了。 這樣設置帶來的收益可能會比您期望或期望的要少。

有關為什么不建議使用2個或更多“繪制線程”的信息,請參閱相關文章:

Java 8添加了一個實驗性的命令行開關,以將相同的線程用於JavaFX應用程序線程和Swing事件分配線程。 這樣做的主要原因是它簡化了編程模型。

一切都落在javafx上,這意味着在執行諸如打開文件選擇器之類的操作時會出現很多暫停。

也許您的代碼效率低下(例如,在UI線程上執行I / O)導致了暫停。

繁重的工作(例如,打開FileChooser)

打開和呈現FileChooser並不繁瑣。 JavaFX可以輕松處理此類操作,而不會降低性能。 與I / O相關的工作可能很耗時,例如,遞歸地遍歷大文件樹以獲取文件屬性。 在這種情況下,您可以做的是生成一個I / O線程,以便在Worker運行它,並通過Platform.runLater定期將部分結果反饋給UI線程。 這樣的方案將很好地工作。 瓶頸不是圖形,因此擁有另一個圖形線程不會帶來任何好處。 瓶頸是速度較慢的I / O系統,並且通過為I / O使用單獨的線程來掩蓋此瓶頸,從而不會影響主UI線程,並且在發生I / O時用戶不會遇到UI凍結的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM