kotlin: 协程调度器

一,协程调度器Coroutine Dispatcher

Dispatchers.Main,它只在 UI 编程平台才有意义,在 Android、Swing 之类的平台上,一般只有 Main 线程才能用于 UI 绘制。
这个 Dispatcher 在普通的 JVM 工程当中,是无法直接使用的。

Dispatchers.Unconfined,代表无所谓,当前协程可能运行在任意线程之上。

Dispatchers.Default,它是用于 CPU 密集型任务的线程池。
一般来说,它内部的线程个数是与机器 CPU 核心数量保持一致的,不过它有一个最小限制 2。

Dispatchers.IO,它是用于 IO 密集型任务的线程池。
它内部的线程数量一般会更多一些(比如 64 个),具体线程的数量我们可以通过参数来配置:kotlinx.coroutines.io.parallelism。

二,代码:

        //处理按钮点击事件
        binding.button1.setOnClickListener {
            runBlocking {
                logX("launch协程之前.") // 1
                launch {
                    logX("launch内部:开始.") // 2
                    delay(1000L)
                    logX("launch内部:结束.") // 3
                }
                logX("launch协程之后.")   // 4
            }
        }


        //处理按钮点击事件
        binding.button2.setOnClickListener {
            runBlocking {
                logX("launch协程之前.")  // 1
//               变化在这里
//                  ↓
                launch(Dispatchers.Unconfined) {
                    logX("launch内部:开始.")  // 2
                    delay(1000L)
                    logX("launch内部:结束.") // 3
                }
                logX("launch协程之后.")    // 4
            }
        }

 

Dispatchers.Unconfined 是一种无线程约束的协程调度器。
它在当前调用帧内执行协程的初始代码,并允许协程在任意挂起函数使用的线程中恢复运行,无需遵循特定线程策略。

一句话总结:Dispatchers.Unconfined 不提供运行协程的线程池,协程在什么地方恢复,就在哪个线程中执行后续代码。

 

其实 Unconfined 代表的意思就是,当前协程可能运行在任何线程之上,不作强制要求。
由此可见,Dispatchers.Unconfined 其实是很危险的。
所以,我们不应该随意使用 Dispatchers.Unconfined。

Dispatchers.Unconfined三个特点:

当你使用Dispatchers.Unconfined时,需要注意以下几点:

  1. 立即执行:协程会在当前线程中立即开始执行,
                   这意味着如果你在主线程中启动一个使用Dispatchers.Unconfined的协程,
                   它将直接在当前线程上运行,而不会排队等待。

  2. 线程切换:尽管协程在启动时可能在当前线程执行,但它可以在执行过程中切换到其他线程。
                   例如,如果你在UI线程上启动一个使用Dispatchers.Unconfined的协程,然后在协程体内部调用一个挂起函数(例如网络请求),
                   这个挂起函数可能会被调度到另一个线程上执行。

  3. 不推荐使用:由于Dispatchers.Unconfined可能导致代码的执行顺序和预期不符(尤其是在UI编程中),它通常不推荐用于生产代码。
                      它可能导致难以调试的竞态条件和不确定的执行顺序,特别是在涉及UI更新的场景中。

三,测试效果:

第一个按钮点击:未指定dispatcher时

第二个按钮点击:指定dispatcher为Dispatchers.Unconfined
可以看到代码中执行顺序的变化

 

posted @ 2025-07-26 11:39  刘宏缔的架构森林  阅读(34)  评论(0)    收藏  举报