我正在制作類似于 minecraft 插件的東西,但 API 都是 Java 語言。
在某些時候,有事件。每個事件都是按順序觸發的,API 將等到一個事件完成,然后再為下一個事件呼叫事件偵聽器。這些事件是從主執行緒呼叫的,這意味著在運行事件偵聽器代碼時沒有其他任何東西在運行,如果您阻塞主執行緒太久,應用程式最終會崩潰。
基本上,我希望當玩家打開庫存時,直接發送一些第一個內容,然后從資料庫中檢索一些第二個內容。在 Java 中,你會做這樣的事情:
private static final List<Item> firstContent = ...;
public static void onInventoryOpenEvent(Inventory inventory) {
inventory.addItems(firstContent);
forkJoinPool.submit(() -> { // "fire and forget"
List<Item> secondContent = retrieveContentFromDB(); // long and blocking
inventory.addItems(secondContent);
});
}
在 kotlin 中,有些人會說要使用GlobalScope,有些人會說不要使用它,但現在我沒有看到除了像這樣使用它之外的任何其他方式:
fun onInventoryOpenEvent(inventory: Inventory) { // not a suspending function
inventory.addItems(firstContent)
GlobalScope.launch {
val secondContent = retrieveContentFromDB() // long and blocking
inventory.addItems(secondContent)
}
}
uj5u.com熱心網友回復:
如果你真的想一勞永逸,讓協程在任何情況下都不會被取消,那么 GlobalScope 是正確的做法。在實踐中,真正觸發并忘記的需要非常少,以至于如果你使用 Kotlin,它會給你一個關于“脆弱 API”的警告,我認為是因為很多新手都在使用它。這在 Android(主要使用 Kotlin)上尤其是一個問題,其中應該在服務而不是協程中處理甚至應該在螢屏外運行的長時間運行的任務。
但是,參考您的示例,如果inventory某些東西可能會過時并且您想在某個時候將其釋放到 GC,您應該使用您自己創建的存盤在屬性中的 CoroutineScope,以便您可以取消它以清除任何正在運行的協程并防止它們掛在應該為 GC 釋放的參考上。如果作用域可能用于多個協程,那么你應該給它一個SupervisorJob().
private val coroutineScope = CoroutineScope(SupervisorJob())
fun onEndOfLifecycle() { // some function called when cleaning up memory
coroutineScope.cancel()
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513761.html
標籤:爪哇多线程科特林kotlin 协程
上一篇:Pythonbs4lxml決議慢
