2017-09-16 58 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