的CoroutineScope是什么
runBlocking {
// some code here
}在Kotlin Coroutines?
当类被垃圾回收时,它是被调用的类的本地,并且协程被垃圾回收吗?如果它还在运行,它会导致内存泄漏吗?
发布于 2021-09-20 17:35:19
与launch或async不同,runBlocking是一个非常特殊的协程构建器,因为它应该在顶层使用。因此,它不在作用域中运行(正如您所看到的,没有CoroutineScope作为接收器)。相反,它应该是结构化并发的“根”。
runBlocking实际上为您提供了一个作用域,因此您可以在其中启动“子”协程。真正重要的是,runBlocking将等待您在该作用域中启动的所有协程(子协程)在返回之前完成。
正在取消runBlocking吗?
如果runBlocking协程挂起(就像您通过取消launch或async的作用域所做的那样),那么您不能真正地在外部取消它本身,因为它不是异步任务-它正在阻塞线程。您可以中断运行它的线程,或者您也可以跟踪嵌套的协程并显式取消它们,以使runBlocking完成。
只有在所有子协程都完成(或被取消)后,runBlocking调用才会返回。抛出一个异常(从内部)也会取消所有子协程,并使runBlocking重新抛出该异常。所以这也是一种从内部“取消”runBlocking的方法。
对于调用它的类是本地的吗?当类被垃圾回收时,协程会被垃圾回收吗?如果它还在运行,它会导致内存泄漏吗?
你可以把runBlocking看作任何阻塞函数,就像Thread.sleep一样,没有更多的魔力了。就像Thread.sleep一样,runBlocking可以从任何函数调用,甚至可以从顶层调用,在这种情况下不会涉及任何类实例。
让我们假设一个类中的一个方法调用runBlocking,并且runBlocking中的任何内容都会挂起很长一段时间(比如长睡眠)。然后,无论是谁调用此方法,都会持有对该实例的引用,直到该方法返回或失败,因此该实例无论如何都不会被垃圾回收。在这种情况下,调用者将挂起,阻塞它在其中运行的任何线程-这就是可能发生泄漏的地方。
使用runBlocking的问题示例
弹簧控制器
如果您在Spring MVC控制器的方法中使用runblocking,Spring可能会为每个线程创建线程,如果runBlocking中有任何东西挂起,您可能会泄漏线程。相反,您可以使用Spring,它允许您直接在WebFlux控制器中使用suspend函数(并添加一个请求超时以自动取消挂起的内容)。
回调
在内部回调中使用runBlocking也可能是危险的。您正在使用的假设的基于回调的应用程序接口可能正在使用线程池回调您,如果runBlocking挂起,它可能会阻塞该线程池。
如果该API支持背压,那么可以阻止它。API还可以以非阻塞的方式支持这一点(就像JDK11的websocket listener,它允许您从回调中返回CompletableStage ),在这种情况下,您应该构建一个Future而不是阻塞。
如果API不支持反压力,您可能不得不在其中创建一个自定义的CoroutineScope和launch-ing协程来处理回调(而不是runBlocking)。当您不再使用基于回调的API时,您必须手动取消该作用域。
https://stackoverflow.com/questions/69257900
复制相似问题