2017-09-16 56 views
1

我在演示Android應用程序中使用Kotlin和Coroutines進行遊戲。Kotlin:跳過協程

這是我有:

fun testCoroutine3() = runBlocking { 
    var num = 0 
    val jobs = List(10_000) { // create a lot of coroutines and list their jobs. 
     launch(CommonPool) { 
      delay(1000L) 
      println(num++) 
     } 
    } 

    for(job in jobs) { 
     job.join() //wait for all jobs to finish 
    } 
    println("FINAL RESULT $num") 
} 

基本上我創建萬個協同程序是等待1秒,打印號碼,然後遞增它的列表。

然後,當所有的工作完成後,我打印最終結果。

(此演示從GitHub Documentation拍攝)現在我的大多數測試運行正常,所有的協同程序幾乎同時運行,而我最終的結果是10000

Log showing Final Result = 10,000

然而,在某些罕見的情況下,我得到最終結果爲9,999

Log showing Final Result = 9,999

這變得更加明顯,當我增加數到50000例如:

Log showing Final Result = 49,998

難道科特林被跳過一些協同程序時,有很多人嗎?在50,000,看起來像跳過了2

或者是在這裏發生的其他事情?

回答

3

num++由兩個操作組成:tmp = num + 1num = tmp。當像你的例子那樣處理多線程時,有些情況下某些操作可能會覆蓋另一個線程的結果,從而導致類似你的例子的情況。

如果您想了解更多信息,請研究「競爭條件」,最終結果取決於兩個獨立流程之間的「競爭」。

+0

這個很有道理啊!任何想法我可以用來確保我得到的最終結果= 10,000?除了做jobs.count – Youssef

+0

唯一的方法來保證是同步對變量的訪問或使用'Atomic *'類來確保每個操作最終被註冊。 – Kiskae

+1

@Youssef通常情況下,您儘量避免使用任何共享的可變狀態。這也將消除這個問題。 – marstran