首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么带有newSingleThreadExecutor的runBlocking块不结束?

带有newSingleThreadExecutorrunBlocking块不结束的原因是因为newSingleThreadExecutor创建的线程池只有一个线程,该线程用于执行runBlocking块中的任务。当runBlocking块中的任务执行完毕后,线程池中的线程并不会立即终止,而是等待新的任务到达。由于runBlocking块没有新的任务到达,所以线程池中的线程会一直保持活动状态,导致runBlocking块不结束。

runBlocking是一个阻塞当前线程的函数,它会等待runBlocking块中的任务执行完毕后才会继续执行后续代码。在这个例子中,由于runBlocking块不结束,所以后续的代码也无法执行。

解决这个问题的方法是在runBlocking块中使用launch函数创建一个协程,并在协程中执行任务。这样,runBlocking块会等待协程执行完毕后结束,而不会一直阻塞。

以下是一个示例代码:

代码语言:txt
复制
import kotlinx.coroutines.*

fun main() {
    runBlocking {
        val job = launch {
            // 在这里执行任务
        }
        job.join() // 等待协程执行完毕
    }
    // 后续代码
}

在这个示例中,launch函数创建了一个协程,并在协程中执行任务。job.join()会等待协程执行完毕后才会继续执行后续代码,从而避免了runBlocking块一直阻塞的问题。

腾讯云相关产品和产品介绍链接地址:

请注意,以上产品仅作为示例,实际选择产品时应根据具体需求进行评估和选择。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Kotlin | 协程使用手册(不间断更新)

,它并不会造成函数阻塞,但是会挂起协程 协程作用域构建器 runBlocking 会阻塞当前线程,直到协程结束。...所以在实际应用中,我们更推荐 : 在执行操作所在指定作用域内启动协程,而非随意使用 协程取消与超时 cancelAndJoin 取消一个协程并等待结束 runBlocking {...我们可以定义异步风格函数来异步调用 playGame 和 playPP,并使用 async 协程建造器并带有一个显式 GlobalScope引用 suspend fun main() {...当前所在线程----main @coroutine#1 当前所在线程----main @coroutine#2 lauch+1 1 lauch+2 lauch+3 为什么 lauch依然运行呢?...协程中取消操作总是通过抛出异常来执行,这样所有的资源管理函数(try{},finally{} 会在取消情况下正常运行 take 获取指定个数发射个数,到达上限将停止发射 runBlocking

2.3K20

Kotlin 协程之Practice

它启动了一个新协程作用域并且在所有子协程执行结束后并没有执行完毕。     ...// runBlocking 和 coroutineScope 主要不同之处在于后者在等待所有的子协程执行完毕时并没有使当前线程阻塞     private fun testCoro() = runBlocking...finally中运行挂起函数就会抛异常 //                print("i am running finally")                 //可以将相应代码包装在...        print("now i can quit")     }       //用户关闭了协程界面,那么协程结束就没有必要了,它可以被取消     //协程取消是协作...,这个协程是轻量级,与其他协程一起并发工作,与launch启动协程不同,launch启动返回一个Job对象     // 不带有任何返回值,而async返回一个Defrred对象一个轻量级非阻塞future

1.1K20

Kotlin 协程上下文和调度器介绍-Dispatchers

挂起后,它恢复线程中协程,而这完全由被调用挂起函数来决定。非受限调度器非常适用于执行不消耗 CPU 时间任务,以及更新局限于特定线程任何共享数据(如UI)协程。...非受限调度器是一种高级机制,可以在某些极端情况下提供帮助而不需要调度协程以便稍后执行或产生希望副作用, 因为某些操作必须立即在协程中执行。非受限调度器不应该在通常代码中使用。...isActive println(s) } //输出 true 说明我当前协程对象是活动。 而为什么要添加“?” 那是因为对象可能为null。...() // 等待请求完成,包括其所有子协程 println("所有的协程结束") } //输出 返回值:父协程本身已经执行完毕了,但我并没有调用方法明确关闭所有子协程, 子协程事务还没有结束...协程:0 结束 协程:1 结束 协程:2 结束 所有的协程结束 我们可以看到,父协程代码已经执行完毕并输出了。

34310

Kotlin语言基础入门到熟悉:Kotlin协程基础

(3000L)  //阻塞主线程防止过快退出 } println("\n示例结束") } 可以看到,runBlocking里使用了delay来延迟。...用了runBlocking主线程会一直**阻塞**直到runBlocking内部协程执行完毕。 也就是runBlocking{ delay }实现了阻塞效果。...runBlocking 与 coroutineScope 看起来类似,因为它们都会等待其协程体以及所有子协程结束。...提取函数重构 将launch { …… }内部代码提取到独立函数中。提取出来函数需要 **suspend** 修饰符,它是**挂起函数**。...前文那个例子,其实也能看到,字符没打印完程序就结束了。 在 **GlobalScope** 中启动活动协程并不会使进程保活。它们就像守护线程。

78400

《Kotin 极简教程》第9章 轻量级线程:协程(2)《Kotlin极简教程》正式上架:

isActive等于 false ,同时 isCompleted等于 true isCancelled 如果当前延迟任务被取消,返回true suspend fun await() 等待此延迟任务完成,而阻塞线程...上下文协程运行在主线程中; 继承了 runBlocking {...}...block.startCoroutine(this, this) } } 其中,参数说明如下: 参数名 说明 context 协程上下文 capacity 通道缓存容量大小 (默认没有缓存) block 协程代码...它由两个主要包组成: kotlin.coroutines.experimental 带有主要类型与下述原语: createCoroutine() startCoroutine() suspendCoroutine...() kotlin.coroutines.experimental.intrinsics 带有甚至更底层内在函数如 : suspendCoroutineOrReturn 大多数基于协程应用程序级API

1.2K20

Kotlin 协程和 Android SQLite API 中线程模型

IO-Thread-1 线程执行结束后才可以继续。...当数据库事务操作都是在一个线程上完成,这样 API 不会有任何问题,但是使用协程之后问题就来了,因为协程是绑定在任何特定线程上。...在事务开始时,Room 会获得 executor 中某个线程控制权,直到事务结束。在事务执行期间,即使调度器因子协程发生了变化,已执行数据库操作仍会被分配到该事务线程上。 ...然后 runBlocking 所创建调度器会将要执行代码分发给已获得线程。另外,Job 被用来挂起和保持线程可用性,直到事务执行完成为止。...// 挂起 runBlocking 协程,直到 controlJob 完成。由于协程是空,所以这将会阻止 runBlocking 立即结束

1.8K20

【Kotlin 协程】协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消协程任务 | 构造超时取消协程任务 )

try…catch…finally 代码 , 在 finally 代码代码 , 即使是协程取消时 , 也会执行 ; 代码示例 : package kim.hsl.coroutine import...(1000) Log.i(TAG, "释放协程占用资源完毕") } } 如果在协程取消后 , finally 代码代码肯定会执行 , 但是如果 finally 中 delay...挂起函数以及之后代码将不会被执行 ; 使用 withContext(NonCancellable) {} 代码 , 可以构造一个无法取消协程任务 , 这样可以避免 finally 中代码无法完全执行..., 但是整个代码被 withContext(NonCancellable) 代码包裹 , 所有的代码执行完毕 ; 23:12:31.014 I 协程任务执行开始 23:12:31.029 I...Log.i(TAG, "协程任务执行结束") // 执行完毕后返回值 // 如果超时则返回 null

1.3K10

kotlin--协程上下文、异常处理

从前面我们可以大致了解了协程玩法,如果一个协程中使用子协程,那么该协程会等待子协程执行结束后才真正退出,而达到这种效果原因就是协程上下文,上下文贯穿了协程生命周期,这套思想和我们app上下文很像...,不能算是全新协程 等等 3.子协程继承父协程时,除了Job会自动创建新实例外,其他3项手动指定的话,都会自动继承父协程,Job对应是协程任务,每次新任务肯定都是新Job对象 有了这些概念后...,而是在根协程中直接使用子协程方式,当然了,协程上下文继承关系,使得我们主协程等待子协程执行完毕后才结束生命 例子4: fun `test context life4`() = runBlocking...,使用了全新上下文协程使用了async启动,哈哈,这就奇怪了,为什么会这样?...,同一继承关系下协程使用await并无法捕获异常,还是会遵循第一条,导致整个协程生命周期结束 fun `test coroutineScope exception5`() = runBlocking

92510

Kotlin Flow 看这一篇 带你入门~

为什么需要Flow 首先我们来回顾下Kotlin中我们如何使用挂起函数,我们在main方法中,调用挂起函数返回一组数据,代码如下所示: suspend fun loadData(): List...,我们可以看到 在main方法协程中,我们可以直接调用loadData方法,这是因为flow构建代码 就是一个suspend函数。...1 2 3 Process finished with exit code 0 我们会发现,如果我们没有调用flowcollect方法,其实不会进入flow代码中,也就是说 Flow中代码直到被...flowOn Flow代码是执行在执行时上下文中,比如 我们不能通过在flow中指定线程来运行Flow代码中代码,如下所示: fun loadData1() = flow { withContext...那么我们如何指定Flow代码上下文呢,我们需要使用flowOn操作符,我们将Flow代码代码指定在IO线程中,代码如下所示: fun loadData1() = flow { for

1.3K30

Coroutine(协程)(三)

channel = Channel() launch { for (x in 1..5) channel.send(x * x) channel.close() // 我们结束发送...fun main() = runBlocking { val channel = Channel(4) // 启动带缓冲通道 val sender = launch...协程内部使用 CancellationException 来进行取消,这个异常会被所有的处理者忽略,所以那些可以被 catch 代码捕获异常仅仅应该被用来作为额外调试信息资源。...每个增量操作都得使用 withContext(counterContext) 从多线程 Dispatchers.Default 上下文切换到单线程上下文。...3.互斥 该问题互斥解决方案:使用永远不会同时执行 关键代码 来保护共享状态所有修改。在阻塞世界中,你通常会为此目的使用 synchronized 或者 ReentrantLock。

49520

Android面试题之Kotlin协程一文搞定

launch 是非阻塞runBlocking 是阻塞。...多个 async 任务是并行,async 返回是一个Deferred,需要调用其await()方法获取结果 runBlocking一般用在测试中,会阻塞当前线程,会等到包裹子协程都执行完毕才退出...LAZY:只有协程被需要时,包括主动调用协程start、join或者await等函数时才会开始调度,如果调度前就被取消,那么该协程将直接进入异常结束状态 @Test fun `test start...,程序结束时候会自动调用close方法,适合文件对象 //use函数在文件使用完毕后会自动调用close函数 BufferedReader(FileReader("xxx")).use { var...it") delay(500L) } } } 如果不想抛出异常,可以用withTimeoutOrNull /* * 超时任务,超时会返回null,超时返回最后

5710

Android面试题之Kotlin异步流、冷流Flow

flow.collect {value -> println(value)} } Flow与其他方式区别 名为flow是Flow类型构建器函数 flow{...}构建代码可以挂起 函数simpleFlow...(也可以用flowOn切换上下文来实现) conflate(),合并发射项,不对每个值进行处理,比如1-3,只处理1和3,中间处理 collectLatest(),取消并重新发射最后一个值 当必须更改...zip操作符用于组合两个流中相关值 2个流是异步 @Test fun `test flow zip`() = runBlocking { val nums = (1..3).asFlow...当运算符中发射器或代码抛出异常时,处理方法: try/catch,捕获下游collect异常 catch函数(上游emit异常,可以在catch中恢复,比如补充数据) @Test fun `test...当流收集完成时(普通情况或异常情况),它可能需要执行一个动作 命令式finally onCompletion声明式处理,onCompletion还能拿到异常信息,但是不能捕获异常,同时能获取上游异常信息和下游异常信息

6610

Kotlin 协程-暂停与取消

所有Kotlinx.coroutines中挂起函数,都是可以被取消。 但是有些情况下,必须等待处理结束了才能取消。 协程正在执行计算任务时候。并且没有检查取消状态。...但是协程仍然打印了两个输出,才在最后结束。 那么,我们如果面临这种情况下,仍然需要在结束时候关闭协程该如何处理? 强制取消-显式检查取消状态 我们有两种方法来使执行计算代码可以被取消。...直接finally里面结束优雅,我们还可以使用withContext(NonCancellable)进行进一步处理。...那么针对超时,我们有一个单独函数来处理 示例: package com.zinyan.general import kotlinx.coroutines.* fun main() = runBlocking...由于Kotlin 将CancellationException异常当做了正常协程执行结束原因。所以我们在上面使用时候,没有出现崩溃异常。而直接使用TimeOut 就会出现崩溃异常了。

66730
领券