Kotlin 协程库v1.7.1的核心模块(kotlinx-coroutines-core)-- kotlinx.coroutines篇

目录

asContextElement:

asCoroutineDispatcher:

js asDeferred:

asExecutor:

js asPromise:

async:

js await:

awaitAll:

awaitCancellation:

cancelAndJoin:

cancelChildren:

CancellableContinuation:

CancellationException:

CloseableCoroutineDispatcher:

CompletableDeferred:

CompletableJob: 

completeWith: 

CompletionHandler:

CoroutineDispatcher:

CoroutineName:

coroutineScope:

CoroutineStart:

Deferred:

 delay:

 Dispatchers:

 ensureActive:

ensurePresent :

ExperimentalCoroutinesApi:

GlobalScope:

handleCoroutineException:

invoke:

IO:

isActive:

job:

joinAll:

launch:

MainScope:

NonCancellable:

plus:

runBlocking:

Runnable:

SupervisorJob:

supervisorScope:

suspendCancellableCoroutine:

withContext:

withTimeout :

withTimeoutOrNull :

yield:


asContextElement:

创建一个协程上下文元素(CoroutineContext.Element),该元素可以被添加到协程上下文中,以便在特定的协程中检索和使用

注意:上下文元素不跟踪线程局部变量的修改
示例

val myThreadLocal = ThreadLocal<String?>()
println(myThreadLocal.get()) // 打印"null"
GlobalScope.launch(Dispatchers.Default + myThreadLocal.asContextElement(value = "foo")) {
    println(myThreadLocal.get()) // 打印“foo”
    withContext(Dispatchers.Main) {
        println(myThreadLocal.get()) // UI线程上 打印“foo”
    }
}
println(myThreadLocal.get())// 打印"null"
asCoroutineDispatcher:

将常规的java.util.concurrent.Executor 转换为 Kotlin 协程中的 CoroutineDispatcher,CoroutineDispatcher是协程中用于调度协程执行的抽象,它决定了协程运行在哪个线程或线程池中。
示例

// 创建一个固定大小的线程池
val executor = Executors.newFixedThreadPool(2)
// 将线程池转换为 CoroutineDispatcher
val dispatcher: CoroutineDispatcher = executor.asCoroutineDispatcher()
// 在指定的调度器上启动协程
runBlocking(dispatcher) {
    launch {
        println("Task 1 is running on ${Thread.currentThread().name}")
    }
    launch {
        println("Task 2 is running on ${Thread.currentThread().name}")
    }
}
// 关闭线程池
executor.shutdown()
js asDeferred:

将JavaScript中的Promise对象转换为Deferred类型
示例

runBlocking {
    val deferredResult = async {
        // 模拟一个异步操作
        delay(1000)
//        Async operation completed
    }

    // 将 Deferred 对象转换为 Deferred 类型
    val convertedDeferred: Deferred<String> = deferredResult.asDeferred()

    // 等待异步操作完成
    val result = convertedDeferred.await()

    println(result)
}
asExecutor:

CoroutineDispatcher转换为Executor接口。这对于与使用Java的一些库和API集成时很有用,因为它们可能期望一个Executor而不是CoroutineDispatcher
示例

val dispatcher: CoroutineDispatcher = Dispatchers.Default

// 使用asExecutor将CoroutineDispatcher转换为Executor
val executor: Executor = dispatcher.asExecutor()

// 然后可以将其用于与期望Executor的Java库或API进行交互
val runnable = Runnable {
    println("Running on executor")
}

executor.execute(runnable)
js asPromise:

Deferred对象转换为JavaScript中的Promise对象。主要用于与基于Promise的异步编程框架
示例

    suspend fun performAsyncTask(): String {
        // Simulate an asynchronous task
        kotlinx.coroutines.delay(1000)
        return "Task completed"
    }

    fun main() {
        // Start an asynchronous task using async
        val asyncTask = lifecycleScope.async {
            performAsyncTask()
        }

        // Convert the async task to a Promise
        val promise: Promise<String> = asyncTask.asPromise()

        // Handle the Promise in JavaScript-like style
        promise.then(
            onFulfilled = { result ->
                console.log("Promise resolved: $result")
            },
            onRejected = { reason ->
                console.error("Promise rejected: $reason")
            }
        )

        // In a real application, you might want to wait for the Promise to complete
        // before exiting the program. This is just a simple example.
    }
async:

Kotlin 协程库提供的一个构建器,用于在协程中执行异步任务。它与 launch 不同,async 返回一个 Deferred 对象,该对象包含异步任务的结果 这个就不写示例了 上面示例有

js await:

毫无阻碍地等待承诺的完成。

awaitAll:

并发执行多个异步任务并等待它们全部完成。你可以使用async启动这些任务,然后使用awaitAll等待它们的完成。
示例

fun main() = runBlocking {
    val deferred1 = async { fetchDataFromNetwork1() }
    val deferred2 = async { fetchDataFromNetwork2() }

    // 等待两个异步任务完成
    val result = try {
        awaitAll(deferred1, deferred2)
    } catch (e: Exception) {
        // 处理异常
    }

    // 得到结果
    println(result)
}

private suspend fun fetchDataFromNetwork1(): String {
    // 模拟从网络获取数据的异步操作
    delay(1000)
    return "Data from Network 1"
}

private suspend fun fetchDataFromNetwork2(): String {
    // 模拟从网络获取数据的异步操作
    delay(1500)
    return "Data from Network 2"
}
awaitCancellation:

在协程中挂起,直到协程被取消。当协程被取消时,该函数将抛出CancellationException,而不是返回Nothing。
示例

fun main() = runBlocking {
    val job = launch {
        try {
            // 执行一些耗时任务
            repeat(1000) { i ->
                println("Task is running: $i")
                delay(500)
            }
        } finally {
            println("Task is cancelled")
        }
    }

    // 模拟一段时间后取消协程
    delay(2500)
    job.cancelAndJoin()

    // 这里的协程将一直挂起,直到它被取消
    awaitCancellation()
}

Task is running: 0
Task is running: 1
Task is running: 2
Task is running: 3
Task is running: 4
Task is cancelled

cancel:

取消操作 
示例

fun main() = runBlocking {
    val job = CoroutineScope(Dispatchers.Default).launch {
        try {
            // 在这里执行一些异步操作,例如网络请求或耗时计算
            withContext(Dispatchers.IO) {
                // 模拟一个耗时操作
                delay(1000)
            }
            // 在异步操作完成后执行一些操作
            println("Task completed successfully")

        } catch (e: CancellationException) {
            // 在取消时的处理
            println("Task was cancelled")
        }
    }
    //取消
    job.cancel()
    delay(5000)//防止跑完 还没打印Task was cancelled就停止了
}


Task was cancelled
cancelAndJoin:

取消任务并挂起调用协程,直到取消的任务完成。示例

fun main() = runBlocking {
    val job = CoroutineScope(Dispatchers.IO).launch {
        try {
            // 模拟一个耗时的操作
            repeat(100) { index ->
                println("Coroutine is running: $index")
                delay(100)
            }
        } finally {
            // 协程完成或取消时执行的清理工作
            println("Coroutine cleanup")
        }
    }

    // 取消并等待协程完成
    job.cancelAndJoin()
}
cancelChildren:

取消指定协程的所有子协程 示例

fun main() = runBlocking {
    startAsyncTasks()
    delay(1500)
    stopAsyncTasks()
    delay(10000)
}
private var parentJob: Job? = null

fun startAsyncTasks() {
    // 创建一个父协程作业
    parentJob = CoroutineScope(Dispatchers.IO).launch {
        try {
            // 启动多个子协程来执行异步任务
            val job1 = async { fetchDataFromNetwork1() }
            val job2 = async { fetchDataFromNetwork2() }

            // 等待所有子协程完成
            val awaitAll = awaitAll(job1, job2)

            // 所有任务完成后的操作
            // ...
            println(awaitAll)
        } catch (e: CancellationException) {
            // 当父协程被取消时,会进入此块
            // 可以在这里处理取消时的清理工作
            // ...
            println("Task was cancelled")
        }
    }
}

fun stopAsyncTasks() {
    // 取消父协程的所有子协程
    parentJob?.cancelChildren()
}

private suspend fun fetchDataFromNetwork1(): String {
    // 模拟从网络获取数据的异步操作
    delay(1000)
    return "Data from Network 1"
}

private suspend fun fetchDataFromNetwork2(): String {
    // 模拟从网络获取数据的异步操作
    delay(3500)
    return "Data from Network 2"
}


Task was cancelled
CancellableContinuation:

提供对协程取消的更细粒度控制,在协程执行期间能够检查和响应取消操作。

StateisActiveisCompletedisCancelled
Active (initial state)truefalsefalse
Resumed (final completed state)falsetruefalse
Canceled (final completed state)falsetruetrue
    +-----------+   resume    +---------+
    |  Active   | ----------> | Resumed |
    +-----------+             +---------+
          |
          | cancel
          V
    +-----------+
    | Cancelled |
    +-----------+

示例

fun main() = runBlocking{
    try {
        val result = withTimeout(5000) {
            // 模拟一个需要时间较长的操作
            performLongRunningOperation()
        }
        // 操作成功完成
        println("Operation result: $result")
    } catch (e: TimeoutCancellationException) {
        // 操作超时
        println("Operation timed out")
    }
}

// 模拟一个需要时间较长的操作
private suspend fun performLongRunningOperation(): String = suspendCancellableCoroutine { continuation ->
    val job = GlobalScope.launch(Dispatchers.IO) {
        // 模拟一个长时间运行的任务
        delay(10000)
        println("任务完成")
        // 如果协程没有被取消,就恢复 continuation
        if (continuation.isActive) {
            println("isActive == ture")
            continuation.resume("Operation completed successfully"){
                println("resume ${it.message}")
            }
        }
    }
    // 注册一个取消回调,以便在协程被取消时取消这个任务
    continuation.invokeOnCancellation {
        println("invokeOnCancellation ${it?.message}")
        job.cancel()
    }
}
CancellationException:

取消异常

CloseableCoroutineDispatcher:

继承至CoroutineDispatcher额外提供了一个关闭它的方法,导致拒绝任何新任务,并清除与当前调度程序关联的所有底层资源
示例

class CustomDispatcher : CloseableCoroutineDispatcher() {
    // 自定义调度逻辑的实现

    override fun dispatch(context: CoroutineContext, block: Runnable) {
        // 在这里实现自定义的调度逻辑
        executor.submit {
            block.run()
        }
    }
    //原子操作
    private val closed = AtomicBoolean(false)

    override val executor: ExecutorService
        get() = Executors.newSingleThreadExecutor()

    override fun close() {
        if (closed.compareAndSet(false, true)) {
            // 在这里执行关闭资源的逻辑
            // 这个示例中简单地关闭线程池
            executor.shutdown()
            println("Closing resources...")
        }
    }
}

fun main() = runBlocking {
    // 示例中使用自定义调度程序
    val customDispatcher = CustomDispatcher()

    customDispatcher.use { customDispatcher ->
        // 使用 withContext 指定自定义调度器
        withContext(customDispatcher) {
            // 在自定义调度器上执行异步任务
            println("Running on custom dispatcher - Thread: ${Thread.currentThread().name}")
        }
    }
}
CompletableDeferred:

CompletableDeferred 是 Kotlin 协程库中的一个类,用于表示异步操作的结果。它是 Deferred 的一个特殊实现,专注于没有返回值的异步操作(Completable Deferred,无返回值)。CompletableDeferred 有两个主要的函数:complete 和 await。

  • complete: 用于完成这个 CompletableDeferred,表示异步操作已经完成。
  • await: 用于等待异步操作完成,它是一个挂起函数,可以在协程中使用。

class MyAsyncTask {
    // 使用 CompletableDeferred 作为异步任务的结果
    private val completableDeferred = CompletableDeferred<Unit>()

    fun doAsyncTask() {
        // 在后台启动一个协程执行异步任务
        GlobalScope.launch {
            // 模拟异步任务的耗时操作
            simulateAsyncOperation()
            // 异步任务完成时调用 complete
            completableDeferred.complete(Unit)
        }
    }

    suspend fun getResult() {
        // 等待异步任务完成
        completableDeferred.await()
        // 这里可以在主线程中处理异步任务完成后的逻辑
    }

    private suspend fun simulateAsyncOperation() {
        // 模拟异步操作的耗时
        println("In the consumption of time.")
        delay(3000)
        println("Time-consuming completion.")
    }
}

fun main() = runBlocking {
    val myAsyncTask = MyAsyncTask()

    // 启动异步任务
    myAsyncTask.doAsyncTask()

    // 等待异步任务完成
    myAsyncTask.getResult()

    println("Async task completed.")
}

In the consumption of time.
Time-consuming completion.
Async task completed.

CompletableJob: 

CompletableJob 在 Job 的基础上添加了一些额外的功能,使得它更适合一些特定的使用场景。CompletableJob 允许你手动完成(complete 一个任务。在协程中,当你使用 launch、async 等构建器创建协程时,它们会返回一个 Job 对象。这个 Job 对象就是协程的引用,你可以使用这个引用来控制协程的生命周期。

    // 创建一个 CompletableJob
    val completableJob = Job()

    // 创建一个 CoroutineScope,并关联上面的 CompletableJob
    val coroutineScope = CoroutineScope(Dispatchers.Default + completableJob)

    // 启动一个协程
    val job = coroutineScope.launch {
        // 协程的逻辑
        delay(1000) // 模拟一些工作
        //任务完成时手动完成 job
        completableJob.complete()
        // 任务完成后,可以执行一些操作
        println("Coroutine completed")
    }

    // 可以添加监听器来处理任务完成的事件
    completableJob.invokeOnCompletion {
        println("Job completed")
        // 可以在这里执行一些额外的操作
    }

    // 在主线程中等待协程完成
    runBlocking {
        //手动完成 job
        job.join()
    }


Coroutine completed
Job completed
completeWith: 

这个方法的作用是将将给定的 Result 对象的结果结果(成功或失败)传递给 CompletableDeferred。completeWith 返回一个布尔值,表示操作是否成功。如果 CompletableDeferred 已经被完成过,那么这个方法将返回 false。

runBlocking{
    val completableDeferred = CompletableDeferred<String>()

    // 在后台线程中模拟异步操作,并将结果传递给 CompletableDeferred
    GlobalScope.launch(Dispatchers.IO) {
        try {
            // 模拟异步操作成功,并将结果传递给 CompletableDeferred
            val result = Result.success("Operation completed successfully")
            completableDeferred.completeWith(result)
        } catch (e: Exception) {
            // 模拟异步操作失败,并将异常传递给 CompletableDeferred
            val result = Result.failure<String>(e)
            completableDeferred.completeWith(result)
        }
    }
    // 等待异步操作的结果
    val result = completableDeferred.await()
    // 打印结果
    println(result)

}
CompletionHandler

对于 Job.invokeOnCompletion 和 CancellableContinuation.invokeOnCancellation 的处理程序
安装的处理程序不应抛出任何异常。如果出现异常,它们将被捕获,封装成 CompletionHandlerException,并重新抛出,可能导致与无关的代码崩溃。传递给处理程序的 cause 的含义: 

  • 当任务正常完成时,cause 为 null。
  • 当任务被正常取消时,cause 为 CancellationException。不应将其视为错误。特别是不应将其报告到错误日志中。
  • 否则,任务失败。

注意:这种类型是支持父子层次结构并允许实现等待 Job 状态的挂起函数的内部机制的一部分。此类型不应在一般应用程序代码中使用。CompletionHandler 的实现必须快速且无锁。

val job = GlobalScope.launch {
        // 协程的代码
        delay(1000)
        throw RuntimeException("Async task failed")
        println("Coroutine completed")
    }

    // 设置协程完成时的处理程序
    job.invokeOnCompletion { cause ->
        when (cause) {
            null -> {
                println("Job completed successfully")
            }
            is CancellationException -> {
                println("Job was cancelled")
            }
            else -> {
                println("Job failed with exception: $cause")
            }
        }
    }

    // 等待协程完成
    runBlocking {
        job.join()
    }


Exception in thread "DefaultDispatcher-worker-1" java.lang.RuntimeException: Exception while trying to handle coroutine exception
	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handlerException(CoroutineExceptionHandler.kt:38)
	at kotlinx.coroutines.CoroutineExceptionHandlerImplKt.handleCoroutineExceptionImpl(CoroutineExceptionHandlerImpl.kt:52)
	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handleCoroutineException(CoroutineExceptionHandler.kt:33)
	at kotlinx.coroutines.StandaloneCoroutine.handleJobException(Builders.common.kt:196)
	at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:229)
	at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:906)
	at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:863)
	at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:828)
	at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:100)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
	Suppressed: java.lang.RuntimeException: Async task failed
		at com.yang.myapplication.MainActivityKt$main$job$1.invokeSuspend(MainActivity.kt:65)
		at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
		... 5 more
Caused by: java.lang.NoClassDefFoundError: android/os/Build$VERSION
	at kotlinx.coroutines.android.AndroidExceptionPreHandler.handleException(AndroidExceptionPreHandler.kt:47)
	at kotlinx.coroutines.CoroutineExceptionHandlerImplKt.handleCoroutineExceptionImpl(CoroutineExceptionHandlerImpl.kt:48)
	... 13 more
Caused by: java.lang.ClassNotFoundException: android.os.Build$VERSION
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 15 more
Exception in thread "DefaultDispatcher-worker-1" java.lang.RuntimeException: Async task failed
	at com.yang.myapplication.MainActivityKt$main$job$1.invokeSuspend(MainActivity.kt:65)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@6cb2c53e, Dispatchers.Default]
Job failed with exception: java.lang.RuntimeException: Async task failed
CoroutineDispatcher:

所有协程调度程序实现扩展的基类

以下是 CoroutineDispatcher 的一些标准实现,它们由 kotlinx.coroutines 提供,并作为 Dispatchers 对象的属性:

  • Dispatchers.Default:用于所有标准构建器,如果它们的上下文中没有指定调度器或任何其他 ContinuationInterceptor。使用一个共享的后台线程池,适用于消耗 CPU 资源的计算密集型协程。
  • Dispatchers.IO:使用一个共享的线程池,在需要时创建线程,设计用于处理 IO 密集型的阻塞操作(如文件 I/O 和阻塞的套接字 I/O)。
  • Dispatchers.Unconfined:在当前调用帧中启动协程执行,直到第一个挂起点,在那时协程构建器函数返回。协程将在稍后由相应的挂起函数使用的任何线程中恢复,而不限制在特定的线程或线程池中。Unconfined 调度器通常不应该在代码中使用。
  • 私有线程池可以使用 newSingleThreadContext 和 newFixedThreadPoolContext 创建。
  • 任意的 java.util.concurrent.Executor 可以使用 asCoroutineDispatcher 扩展函数转换为调度器。

在 Android 中,你可以使用这些调度器来指定协程的执行上下文,以便它们在适当的线程或线程池中运行,从而更好地管理并发和异步操作。

CoroutineName:

提供了一种在协程上下文中携带协程名字信息的方式,使得在调试和日志输出时能够更容易地追踪协程的执行。

// 在主线程启动一个协程
    runBlocking {
        // 在 IO 线程执行异步操作
        val result = withContext(Dispatchers.IO) {
            // 协程名字为 "IOOperation"
            val operationName = CoroutineName("IOOperation")

            // 在 IO 线程中携带协程名字
            val result = withContext(operationName + Dispatchers.IO) {
                // 执行一些耗时的 IO 操作
                "Result from IO operation"
            }

            // 打印协程名字
            println("Coroutine name: ${operationName.name}")

            result
        }

        // 打印异步操作的结果
        println("Result on Main thread: $result")
    }


Coroutine name: IOOperation
Result on Main thread: Result from IO operation
coroutineScope:

另一种创建 CoroutineScope 并使用此范围调用挂起块的方式。它设计用于并发分解工作。提供的范围从外部范围继承其 coroutineContext,但覆盖上下文的 Job。如果此范围内的任何子协程失败,则此范围失败,其余的所有子协程都会被取消。

suspend fun showSomeData() = coroutineScope {
    val data = async(Dispatchers.IO) {
        // ... 为主线程加载一些 UI 数据 ...
    }

    withContext(Dispatchers.Main) {
        doSomeWork()
        val result = data.await()
        display(result)
    }
}
CoroutineStart:

CoroutineStart 是 Kotlin 协程库中用于协程启动的枚举类,它定义了在协程构建器(如 launch、async 等)中用作 start 参数的选项。以下是这些选项的简要概述:

  • DEFAULT:默认选项,会根据协程的上下文立即安排协程执行。
  • LAZY:懒启动选项,只有在需要的时候才启动协程。
  • ATOMIC:原子启动选项,在不可取消的方式下,根据协程的上下文立即安排协程执行。
  • UNDISPATCHED:无调度启动选项,会在当前线程中立即执行协程,直到遇到第一个挂起点。
    runBlocking {
        // 示例:使用 DEFAULT 启动协程
        val job = GlobalScope.launch(start = CoroutineStart.DEFAULT) {
            println("Coroutine started")
            delay(1000)
            println("Coroutine completed")
        }
        job.join()
    
        // 示例:使用 LAZY 启动协程
        val lazyJob = GlobalScope.launch(start = CoroutineStart.LAZY) {
            println("Lazy Coroutine started")
            delay(1000)
            println("Lazy Coroutine completed")
        }
        lazyJob.start() // 手动启动
        lazyJob.join()
    
        // 示例:使用 ATOMIC 启动协程
        val atomicJob = GlobalScope.launch(start = CoroutineStart.ATOMIC) {
            println("Atomic Coroutine started")
            delay(1000)
            println("Atomic Coroutine completed")
        }
        atomicJob.join()
    
        // 示例:使用 UNDISPATCHED 启动协程
        val undispatchedJob = GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) {
            println("Undispatched Coroutine started")
            delay(1000)
            println("Undispatched Coroutine completed")
        }
        undispatchedJob.join()
    }
Deferred:

一种非阻塞的可取消 future。它是 Job 的子类,表示具有结果的任务。

fun main() = runBlocking {
    // 创建一个 Deferred 对象
    val deferred: Deferred<Int> = async {
        delay(1000) // 模拟耗时操作
        42 // 返回结果
    }

    // 在不阻塞线程的情况下等待 Deferred 完成,并获取结果
    val result: Int = deferred.await()
    println("Result: $result")
}


Result: 42
 delay:

提供的一个挂起函数,用于在协程中进行延迟操作,而不会阻塞线程。它有两个重载形式

  • suspend fun delay(timeMillis: Long)
  • suspend fun delay(duration: Duration)

这两个函数都能够将协程挂起一段时间,然后再继续执行。它们的作用是为了模拟暂停,而不是直接阻塞线程。

runBlocking {
    println("Start")
    delay(Duration.ofSeconds(1)) // 挂起协程 1 秒
    println("After delay")
}
 Dispatchers:

参考CoroutineDispatcher

 ensureActive:

确保当前协程仍然保持活跃状态,如果协程或作业不再活跃,它会抛出 CancellationException 异常。该函数提供了更精确的异常,因此你可以在协程内捕获 CancellationException,以便更好地处理取消的情况。

runBlocking {
    launch {
        try {
            // 模拟耗时操作
            repeat(1000) {
                // 确保协程仍处于活动状态
                ensureActive()

                // 一些工作
                println("Working $it")
                delay(100)
            }
        } catch (e: CancellationException) {
            // 在协程被取消时执行的代码
            println("Coroutine cancelled: ${e.message}")
        }
    }

    // 等待一段时间,然后取消协程
    delay(500)
    coroutineContext.cancelChildren()
}




Working 0
Working 1
Working 2
Working 3
Working 4
Coroutine cancelled: StandaloneCoroutine was cancelled
ensurePresent

用于检查当前协程上下文中是否包含指定的 ThreadLocal 实例。如果该 ThreadLocal 不存在于协程上下文中,ensurePresent 会抛出 IllegalStateException。这有助于避免在协程中使用过时的或无效的 ThreadLocal 值,从而提高代码的健壮性

ExperimentalCoroutinesApi:

标记仍处于实验的coroutines API中,这意味着相应声明的设计存在公开的问题,这些问题可能会(也可能不会)导致它们在将来发生变化。粗略地说,这些声明有可能在不久的将来被弃用,或者它们行为的语义可能会以某种方式改变,这可能会破坏一些代码。

GlobalScope:

全局作用域用于启动顶级协程,这些协程在整个应用程序生命周期内运行,不会过早取消。请在有限的情况下合理安全地使用。

    @OptIn(DelicateCoroutinesApi::class)
    GlobalScope.launch {
        while (true) {
            delay(1000)
            println("GlobalScope run once")
        }
    }
handleCoroutineException:

介绍:为协程构建器的实现提供一个辅助函数,是为了防止异常丢失而设计的,是一种最后的手段。用于处理那些在协程中未捕获且不能通过正常方式(比如使用 try-catch)处理的异常。

runBlocking {
    val exceptionHandler = CoroutineExceptionHandler { _, exception ->
        println("Caught an exception: $exception")
    }

    // 在这里,我们故意抛出一个异常,但由于有异常处理器,异常将被捕获。
    val job = launch(exceptionHandler) {
        throw RuntimeException("Intentional exception")
    }
    
    job.join() // 等待作业完成
    
}
invoke:

扩展函数,其作用是在指定的 CoroutineDispatcher 上调用给定的挂起块,并等待其完成,然后返回结果。

runBlocking {
    // 在 IO 线程上执行 fetchDataFromNetwork
    val networkData = Dispatchers.IO.invoke {
        fetchDataFromNetwork()
    }
    // 在默认的调度器上执行 fetchDataFromDisk
    val diskData = Dispatchers.Default.invoke {
        fetchDataFromDisk()
    }
    //2000+3000 后打印
    println("Network Data: $networkData")
    println("Disk Data: $diskData")
}


Network Data: Data from network
Disk Data: Data from disk
IO:

Dispatchers.IO 是一个专门设计用于将阻塞 I/O 任务卸载到共享线程池的协程调度器

isActive:

介绍:检查协程是否处于活动状态的属性

runBlocking {
    val job = launch {
        repeat(1000) { i ->
            // 检查协程是否仍处于活动状态
            if (!isActive) {
                println("Cancelling due to isActive = false")
                return@launch
            }
            println("I'm sleeping $i ...")
            delay(500L)
        }
    }
    delay(1300L) // 等待一段时间
    // 取消协程
    println("main: Cancelling the job!")
    job.cancelAndJoin()
    println("main: Quitting")
    //coroutineContext.isActive表达式是的快捷方式get(Job)?.isActive ?: true
    //while (coroutineContext.isActive) {
    //    do some computation
    //}
}


I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
main: Cancelling the job!
main: Quitting
job:

是 Kotlin 协程中的一个关键概念,用于表示一个可以取消的、带有生命周期的任务

  • Cancellation(取消): Job 可以被取消,用于中断任务的执行。取消一个 Job 会导致它的所有子 Job 也被递归地取消。
  • Hierarchy(层次结构): Job 可以组成父子关系的层次结构,其中父 Job 的取消会立即取消所有子 Job。
  • 状态管理: Job 有多个状态,包括 New、Active、Completing、Cancelling、Cancelled 和 Completed。这些状态反映了 Job 的生命周期。
    StateisActiveisCompletedisCancelled
    New (optional initial state)falsefalsefalse
    Active (default initial state)truefalsefalse
    Completing (transient state)truefalsefalse
    Cancelling (transient state)falsefalsetrue
    Cancelled (final state)falsetruetrue
    Completed (final state)falsetruefalse
  • Exception Handling(异常处理): 通过 Job,你可以处理任务执行过程中的异常,区分正常取消和异常取消。
  • Concurrency and synchronization(并发和同步): Job 及其派生接口的所有函数都是线程安全的,可以从并发的协程中安全地调用,无需外部同步。
val job: Job = GlobalScope.launch {
        // 协程的执行逻辑
        delay(1000)
        println("Coroutine completed")
    }

    // 在这里,我们可以对协程进行取消
    // job.cancel()

    // 等待协程完成
    runBlocking {
        job.join()
    }
val job: CompletableJob = Job()

    GlobalScope.launch(job) {
        // 协程的执行逻辑
        delay(1000)
        println("Coroutine completed")
    }

    // 在这里,我们可以对协程进行取消
    // job.complete()

    // 等待协程完成
    runBlocking {
        job.join()
    }
joinAll:

用于挂起当前协程,直到传递的所有 Job 完成为止。这是一个方便的方法,可以等待多个协程的完成,而不必在代码中使用 job.join() 多次。

  • 挂起当前协程直到所有给定的 Job 完成
    runBlocking {
        val job1 = launch { /* 协程1的逻辑 */ }
        val job2 = launch { /* 协程2的逻辑 */ }
        val job3 = launch { /* 协程3的逻辑 */ }
        joinAll(job1, job2, job3)
    }
  • 挂起当前协程直到集合中的所有 Job 完成
    runBlocking {
        val jobs = listOf(
            launch { /* 协程1的逻辑 */ },
            launch { /* 协程2的逻辑 */ },
            launch { /* 协程3的逻辑 */ }
        )
        jobs.joinAll()
    }
launch:

启动协程的一个函数

MainScope:

介绍:为UI组件创建主协同作用域我一般理解为Android的Activity协程作用域

class MyAndroidActivity {
    private val scope = MainScope()

    override fun onDestroy() {
        super.onDestroy()
        scope.cancel()
    }
}
NonCancellable:

一个特殊的 Job 对象,用于创建一个非可取消的协程。它是为了在某些代码块中防止被取消而设计的,通常与 withContext 函数一起使用。
注意:NonCancellable 并不是为了用在 launch、async 等协程构建器中的。如果你使用

launch(NonCancellable) { ... }

不仅新启动的任务不会在父任务被取消时取消,整个父子关系也会被切断。父任务将不等待子任务完成,也不会在子任务出现崩溃时被取消。

fun main() = runBlocking {
    val coroutineScope = CoroutineScope(Dispatchers.IO).launch {
        withContext(NonCancellable+Dispatchers.Default) {
            repeat(10){
                delay(1000)
                println("NonCancellable print $it")
            }
        }
    }
    coroutineScope.cancel()
    //防止整个线程退出 测试用
    delay(19000)
}



NonCancellable print 0
NonCancellable print 1
NonCancellable print 2
NonCancellable print 3
NonCancellable print 4
NonCancellable print 5
NonCancellable print 6
NonCancellable print 7
NonCancellable print 8
NonCancellable print 9
plus:

扩展函数,它的作用是将指定的协程上下文(CoroutineContext)添加到当前协程作用域 (CoroutineScope) 中,并覆盖当前作用域上下文中的相应键。这是为了方便地创建一个新的协程作用域,其中包含了当前作用域的上下文以及额外添加的上下文。
比如上面“NonCancellable+Dispatchers.Default”

runBlocking:

运行一个新的协程阻碍当前线程,直到它完成。这个函数不应该在协程中使用。它旨在将常规的阻塞代码与以挂起方式编写的库连接起来,以便在main函数和测试中。

Runnable:

用于表示一个可以在异步环境中执行的任务。在 kotlinx.coroutines 中,这个接口被扩展,以支持协程调度

class MyRunnable : Runnable {
    override fun run() {
        println("Hello from Runnable!")
    }
}

// 在协程中执行
fun main() = runBlocking {
    val runnable = MyRunnable()
    val dispatcher: CoroutineDispatcher = Dispatchers.Default
    dispatcher.dispatch(coroutineContext,runnable)
}




Hello from Runnable!
SupervisorJob:

一种特殊类型的 Job,它用于创建协程的层级结构,其中子协程的失败不会影响其它子协程。这允许在协程的层级结构中灵活地处理失败。supervisor可以实施自定义策略来处理其子项的失败。
注意:不管如何父线程要是崩了子协程一样也是活不了的

  • launch创建的子协程,可以通过上下文中的CoroutineExceptionHandler来处理。(实施自定义策略)
  • async创建的子协程,可以通过Deferred.await对结果延迟值进行处理(也需要实施自定义策略不然结果返回一样崩)
     runBlocking{
    
        val supervisor = SupervisorJob(coroutineContext.job) // 创建一个 SupervisorJob 作为子协程
        val coroutineScope = CoroutineScope(supervisor) // 使用 supervisor 作为协程的 Job
        coroutineScope.launch {
            // 执行一些操作
            delay(1000)
            println("Hello from SupervisorJob launch")
            throw RuntimeException("Child Coroutine 1 failed!")
        }
        coroutineScope.async {
            // 执行一些异步操作
            delay(1500)
            println("Hello from SupervisorJob async")
        }
    
        CoroutineScope(supervisor).launch{
            // 执行一些异步操作
            delay(100)
            println("Hello from launch1")
            //throw RuntimeException("lead to Parent Coroutine 1 failed!")
            delay(2000)
            println("Hello from launch2")
        }
    
    }
    
    //这玩意我放fun main 跑的时候居然一直在运行很奇怪
    
    Hello from launch1
    Hello from SupervisorJob launch
    Exception in thread "DefaultDispatcher-worker-2" java.lang.RuntimeException: Exception while trying to handle coroutine exception
    	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handlerException(CoroutineExceptionHandler.kt:38)
    	at kotlinx.coroutines.CoroutineExceptionHandlerImplKt.handleCoroutineExceptionImpl(CoroutineExceptionHandlerImpl.kt:52)
    	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handleCoroutineException(CoroutineExceptionHandler.kt:33)
    	at kotlinx.coroutines.StandaloneCoroutine.handleJobException(Builders.common.kt:196)
    	at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:229)
    	at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:906)
    	at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:863)
    	at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:828)
    	at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:100)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    	Suppressed: java.lang.RuntimeException: Child Coroutine 1 failed!
    		at com.yang.myapplication.MainActivityKt$main$1$1.invokeSuspend(MainActivity.kt:82)
    		at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    		... 5 more
    Caused by: java.lang.NoClassDefFoundError: android/os/Build$VERSION
    	at kotlinx.coroutines.android.AndroidExceptionPreHandler.handleException(AndroidExceptionPreHandler.kt:47)
    	at kotlinx.coroutines.CoroutineExceptionHandlerImplKt.handleCoroutineExceptionImpl(CoroutineExceptionHandlerImpl.kt:48)
    	... 13 more
    Caused by: java.lang.ClassNotFoundException: android.os.Build$VERSION
    	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    	... 15 more
    Exception in thread "DefaultDispatcher-worker-2" java.lang.RuntimeException: Child Coroutine 1 failed!
    	at com.yang.myapplication.MainActivityKt$main$1$1.invokeSuspend(MainActivity.kt:82)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@3ca7b389, Dispatchers.Default]
    Hello from SupervisorJob async
    Hello from launch2
    
supervisorScope:

快捷的创建上述SupervisorJob

runBlocking{

    supervisorScope {
        launch {
            delay(1000)
            println("Hello from SupervisorJob launch")
            throw RuntimeException("Child Coroutine 1 failed!")
        }
        async {
            delay(1500)
            println("Hello from SupervisorJob async")
        }
        launch {
            delay(2000)
            println("Hello from SupervisorJob launch")
        }
    }
    
    launch{
        delay(2500)
        println("Hello from launch2")
        coroutineContext.job.cancel()
    }

}



Hello from SupervisorJob launch
Exception in thread "main" java.lang.RuntimeException: Exception while trying to handle coroutine exception
	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handlerException(CoroutineExceptionHandler.kt:38)
	at kotlinx.coroutines.CoroutineExceptionHandlerImplKt.handleCoroutineExceptionImpl(CoroutineExceptionHandlerImpl.kt:52)
	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handleCoroutineException(CoroutineExceptionHandler.kt:33)
	at kotlinx.coroutines.StandaloneCoroutine.handleJobException(Builders.common.kt:196)
	at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:229)
	at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:906)
	at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:863)
	at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:828)
	at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:100)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
	at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
	at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:518)
	at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:500)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at com.yang.myapplication.MainActivityKt.main(MainActivity.kt:74)
	at com.yang.myapplication.MainActivityKt.main(MainActivity.kt)
	Suppressed: java.lang.RuntimeException: Child Coroutine 1 failed!
		at com.yang.myapplication.MainActivityKt$main$1$1$1.invokeSuspend(MainActivity.kt:79)
		at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
		... 15 more
Caused by: java.lang.NoClassDefFoundError: android/os/Build$VERSION
	at kotlinx.coroutines.android.AndroidExceptionPreHandler.handleException(AndroidExceptionPreHandler.kt:47)
	at kotlinx.coroutines.CoroutineExceptionHandlerImplKt.handleCoroutineExceptionImpl(CoroutineExceptionHandlerImpl.kt:48)
	... 23 more
Caused by: java.lang.ClassNotFoundException: android.os.Build$VERSION
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 25 more
Exception in thread "main" java.lang.RuntimeException: Child Coroutine 1 failed!
	at com.yang.myapplication.MainActivityKt$main$1$1$1.invokeSuspend(MainActivity.kt:79)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
	at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
	at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:518)
	at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:500)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at com.yang.myapplication.MainActivityKt.main(MainActivity.kt:74)
	at com.yang.myapplication.MainActivityKt.main(MainActivity.kt)
	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@58701e8c, BlockingEventLoop@951461a]
Hello from SupervisorJob async
Hello from SupervisorJob launch
Hello from launch2

suspendCancellableCoroutine:

一个用于支持协程挂起的函数。它的主要作用是允许你在协程中等待一个单次回调的结果,并将结果返回给调用方。它提供了对取消的支持,确保在协程取消时及时清理资源。

val mockApi = MockApi()

suspend fun awaitCallback() = suspendCancellableCoroutine { continuation ->
    val callback = object : Callback {
        override fun onCompleted(value: String) {
            println("onCompleted $value")
            // 用回调提供的值恢复协程
            continuation.resume(value)
        }
        override fun onApiError(cause: Throwable) {
            // 用回调提供的异常恢复协程
            continuation.resumeWithException(cause)
        }
    }
    mockApi.register(callback)
    continuation.invokeOnCancellation{
        mockApi.unregister(callback)
    }
}

class MockApi : Api {
    private var callback: Callback? = null

    override fun register(callback: Callback) {
        this.callback = callback
    }

    override fun unregister(callback: Callback) {
        // 在取消时注销回调
        this.callback = null
    }

    fun triggerCallback(value: String) {
        runBlocking {
            delay(2000)
            println("Send Completed")
            callback?.onCompleted(value)
        }
    }

    fun triggerError(cause: Throwable) {
        runBlocking {
            delay(2000)
            println("Send ApiError")
            callback?.onApiError(cause)
        }
    }
}

interface Api {
    fun register(callback: Callback)
    fun unregister(callback: Callback)
}

interface Callback {
    fun onCompleted(value: String)
    fun onApiError(cause: Throwable)
}

// 在协程中执行
fun main():Unit =runBlocking{
    //开个子协程
    launch {
        try {
            val result = awaitCallback()
            println("Callback completed with result: $result")
        } catch (e: Throwable) {
            println("Callback failed with exception: $e")
        }
        //等待回调的结果返回完成 继续执行
        println("Continue to perform the task ")
    }
    // 模拟成功的回调
    mockApi.triggerCallback("Success!")
    //mockApi.triggerError(Throwable("Error"))
}


Send Completed
onCompleted Success!
Callback completed with result: Success!
Continue to perform the task 
withContext:

在不同的协程上下文中执行挂起函数。它的作用是在指定的协程上下文中执行一个挂起函数块,并在该块执行完成后返回结果

suspend fun exampleFunction() = withContext(Dispatchers.IO) {
    // 在 IO 线程中执行耗时操作,例如网络请求或文件 I/O
    delay(1000) // 模拟耗时操作
    return@withContext "Result from withContext"
}

fun main() = runBlocking {
    val result = exampleFunction()
    println(result)
}


Result from withContext
withTimeout :

挂起函数并在设置超时时间,如果超过了指定的时间,将抛出 TimeoutCancellationException 异常。这有助于在异步操作中设置超时,防止长时间等待或阻塞。

suspend fun performAsyncTask(): String {
    delay(3000) // 模拟一个耗时的异步任务
    return "Task completed successfully!"
}

fun performBlockingTask(): String {
    Thread.sleep(3000) // 模拟一个阻塞任务 
    return "Blocking task completed successfully!"
}

fun main() = runBlocking {
    try {
        val result = withTimeout(2000) {
            performAsyncTask()
            //performBlockingTask()
        }
        println(result)
    } catch (e: TimeoutCancellationException) {
        println("Task timed out!")
    }
}



Task timed out!
//Blocking task completed successfully!
withTimeoutOrNull :

在协程中设置超时。它的作用是在指定的时间内运行一个挂起的代码块,并在超时时返回 null,而不是抛出异常。
超时会导致代码块内正在执行的代码被取消,并且在代码块内部激活或下一次激活可取消的挂起函数时,会抛出 TimeoutCancellationException 异常

runBlocking {
    val result = withTimeoutOrNull(3000) {
        // 在此处执行可能耗时的操作
        delay(5000) // 模拟一个长时间的操作
        "Operation completed"
    }

    if (result != null) {
        println("Success: $result")
    } else {
        println("Timeout occurred")
    }
}



Timeout occurred
yield:

将当前协程的执行权交出,让同一调度器上的其他协程有机会执行。它是一种协作式多任务处理的机制,允许协程在不阻塞线程的情况下进行切换。

suspend fun launchWorker() = CoroutineScope(Dispatchers.Default).launch{
    repeat(10) {
        println("Worker coroutine is working $it")
        delay(50)
        // 使用 yield 让出执行权
        yield()
    }
}

fun main() = runBlocking {
        val job = launchWorker()
        // 主协程做一些其他事情
        repeat(5) {
            println("Main coroutine is doing some work $it")
            delay(100)
        }
        // 等待工作协程完成
        job.cancel()
}




Main coroutine is doing some work 0
Worker coroutine is working 0
Worker coroutine is working 1
Main coroutine is doing some work 1
Worker coroutine is working 2
Worker coroutine is working 3
Main coroutine is doing some work 2
Worker coroutine is working 4
Worker coroutine is working 5
Main coroutine is doing some work 3
Worker coroutine is working 6
Main coroutine is doing some work 4
Worker coroutine is working 7
Worker coroutine is working 8
Worker coroutine is working 9
  • 42
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值