kotlin: 用两种方式比较协程是否在并行

一,用runBlocking创建协程

1,代码:

       binding.button1.setOnClickListener {
            System.setProperty("kotlinx.coroutines.debug", "on")

            val count = AtomicInteger()
            val format = SimpleDateFormat("HH:mm:ss")
            runBlocking {

                repeat(10) { index ->
                    launch {
                        println("协程-$index,${Thread.currentThread().name},启动")
                        var start = System.currentTimeMillis()
                        while (true) {
                            val end = System.currentTimeMillis()
                            if (end - start >= 2000) {
                                // 第9次结束循环,所以只能打印8次当前时间
                                if (count.incrementAndGet() >= 9) break

                                // 每2秒打印一下当前时间
                                println("协程-$index,${Thread.currentThread().name},${format.format(start)}")
                                start = end
                            }
                        }
                    }
                }
            }
        }

2,测试效果:

3,总结:

runBlocking的启动的子协程并不是并行的,
协程-0先启动,然后协程-0打印了8个当前时间结束了,然后协程-1才启动,
因为总共只打印8次当前时间,都被协程-0打印完,所以协程-1和后面的协程没得打印了,
如果协程-0和后面的协程是并行的话,不会由一个协程把时间打印完,而应该是多个协程并行打印
这是因为这些协程在同一个线程上,所以没有做到并行

二,使用GlobalScope创建协程

1,代码:

        binding.button1.setOnClickListener {

            System.setProperty("kotlinx.coroutines.debug", "on")

            val count = AtomicInteger()
            val format = SimpleDateFormat("HH:mm:ss")
            runBlocking {
                GlobalScope.launch {
                    repeat(10) { index ->
                        launch {
                            println("协程-$index,${Thread.currentThread().name},启动")
                            var start = System.currentTimeMillis()
                            while (true) {
                                val end = System.currentTimeMillis()
                                if (end - start >= 2000) {
                                    // 第9次结束循环,所以只能打印8次当前时间
                                    if (count.incrementAndGet() >= 9) break

                                    // 每2秒打印一下当前时间
                                    println(
                                        "${Thread.currentThread().name},协程-$index,${
                                            format.format(
                                                start
                                            )
                                        }"
                                    )
                                    start = end
                                }
                            }
                        }
                    }
                }.join()
            }

        }

2,测试效果:

3,总结:

我们启动了10个协程,这次不一样,有4个协程同时运行了,
因为GlobalScope.launch使用线程池,有4个线程,
我的电脑是4核心CPU,所以只有4个线程,对应启动了4个子协程,
每个子协程打印了两次时间,4个子协程打印完了,
另外6个子协程才启动,并不是10个协程同时启动并行执行,
所以总结就是:
kotlin的协程并发需要依赖于线程,
它的用途更多的是提升线程的性能

 

posted @ 2025-07-19 07:47  刘宏缔的架构森林  阅读(12)  评论(0)    收藏  举报