簡體   English   中英

如何將 Java 線程轉換為 Kotlin 協程?

[英]How to convert Java Threads to Kotlin coroutines?

我有這個“丑陋的” Java 代碼,我需要轉換為 Kotlin 慣用協程,但我不太明白如何。

Thread[] pool=new Thread[2*Runtime.getRuntime().availableProcessors()];
        for (int i=0;i<pool.length;i++)
            pool[i]=new Thread(){
                public void run() {
                    int y; while((y=yCt.getAndIncrement())<out.length) putLine(y,out[y]);
                }
            };
        for (Thread t:pool) t.start();
        for (Thread t:pool) t.join();

我認為可以使用 runBlocking 來實現,但我該如何處理 availableProcessors 計數?

我會在這里做一些假設:

  1. putLine()是 CPU 密集型操作,而不是 IO 操作。 我假設這是因為它是使用 2 * CPU 內核的線程數執行的,這通常用於 CPU 密集型任務。
  2. 我們只需要為 out 中的每個項目out putLine() 從上面的代碼中,不清楚yCt最初是否為0
  3. out並不像數百萬個項目那樣龐大。
  4. 您不會在 Kotlin 中尋找 1:1 的相同代碼,而是尋找它的等效代碼。

那么解決方案真的很簡單:

coroutineScope {
    out.forEachIndexed { index, item ->
        launch(Dispatchers.Default) { putLine(index, item) }
    }
}

幾句解釋:

  • Dispatchers.Default協程調度器專門用於CPU計算,其線程數取決於CPU核數。 我們不需要創建自己的線程,因為協程提供了合適的線程池。
  • 我們不手動處理任務隊列,因為協程是輕量級的,我們可以改為只為每個項目安排一個單獨的協程——它們將自動排隊。
  • coroutineScope()等待它的孩子,所以我們不需要手動等待所有異步任務。 所有任務完成后,將執行放在coroutineScope()下的任何代碼。

Java/threads 和 Kotlin/coroutines 代碼之間的行為存在一些差異:

  • Dispatchers.Default默認情況下線程數 = CPU 內核,而不是 2 * CPU 內核。
  • 在協程解決方案中,如果任何任務失敗,整個操作都會拋出異常。 在原始代碼中,錯誤被忽略,應用程序繼續不一致 state。
  • 在協程解決方案中,線程池與應用程序的其他組件共享。 這可能是期望的行為,也可能不是。

暫無
暫無

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

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