Kotlin: Coroutines—simple application

introduce:

Kotlin Coroutines is a concurrent design pattern for simplifying asynchronous code. It is based on the concept of coroutines and allows the suspension and resumption of execution on a single thread, thereby managing long-running tasks. A coroutine is similar to a thread, but is not tied to a specific thread and can have its execution suspended in one thread and resumed in another.

Features of Kotlin Coroutines include:

  1. Lightweight: Coroutines can run multiple coroutines on a single thread, because coroutines support suspension and will not block the thread running the coroutine. Suspending saves memory than blocking and supports multiple parallel operations.
  2. Fewer memory leaks: Use structured concurrency to perform multiple operations within a scope.
  3. Built-in cancellation support: Cancellation operations are automatically propagated throughout the entire running coroutine hierarchy.
  4. Jetpack integration: Many Jetpack libraries include extensions that provide full coroutine support. Some libraries also provide their own coroutine scopes that can be used for structured concurrency.

When using Kotlin Coroutines, developers need to understand the life cycle of the coroutine in order to correctly control the suspension and resumption of the coroutine. Theoretically, since coroutines do not involve operating system scheduling, they operate in user mode, and threads need to switch between user mode and kernel mode, so coroutines perform better. However, different languages ​​may have differences in implementation. For example, the underlying implementation of Kotlin coroutines has thread switching, so asynchronous tasks may be executed on another thread.

In summary, Kotlin Coroutines is a lightweight, efficient concurrent programming tool suitable for handling asynchronous tasks and long-running operations. By using coroutines, developers can simplify code structure and better manage concurrent execution.

Guide package

Guide package website:         https://mvnrepository.com/

dependencies {
    ...
    //加入2个
// https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")

    // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-android
    runtimeOnly("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")


}

1.launch is asynchronous and does not block threads

package org.example

import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.system.measureTimeMillis

/***
 * Coroutines 协程
 * 轻量级线程
 * 生命周期控制
 * 阻塞 非阻塞
 * var
 * val
 * const val
 */
class CoroutinesTest {
    /**
     * CoroutineScope
     * GlobalScope.launch  异步 不阻塞线程
     * 返回 Job 用于控制协程 取消协程...
     * 一个可以用来创建子执行上下文的方法。你可以用它来启动一个新的执行上下文,该上下文可以在异步任务中独立运行,而不会影响应用的其他部分
     * 用途 :用于创建新的执行上下文,这些上下文可以独立运行,用于执行需要独立生命周期的异步任务。
     * 生命周期:创建的执行上下文具有自己的生命周期,你可以在需要时启动和停止它。
     * 并发性:创建的执行上下文也可以并发运行,但它更加灵活,可以用于更细粒度的控制
     * 取消:创建的执行上下文可以通过调用 Isolate.kill() 方法来停止
     * 性能和资源使用:允许创建独立的执行上下文,这可以更好地控制资源和性能,特别是在需要并发处理大量任务时。
     * 隔离性:创建的执行上下文是隔离的,这有助于避免不同任务之间的冲突和相互影响。
     * 错误处理:错误处理方式更加灵活,可以通过捕获异常或使用其他错误处理机制来处理。
     */
    @OptIn(DelicateCoroutinesApi::class)
    fun testLaunch() {
        val time: Long = measureTimeMillis {
            GlobalScope.launch {
                Thread.sleep(1000)
                println("testLaunch 中的  GlobalScope.launch 线程${Thread.currentThread()} hi hellow")
            }

            GlobalScope.launch {
                Thread.sleep(1000)
                println("testLaunch 中的  GlobalScope.launch2 线程${Thread.currentThread()} hi hellow 第二个")
            }
            //停一下等待 上面线程执行完成
            Thread.sleep(2200)
            println("我是最下面的数据")
        }
        println("函数总耗时:$time")
    }
}


fun main() {

    val ff = coroutinesTest();
    ff.testLaunch();
}

operation result:

testLaunch 中的  GlobalScope.launch2 线程Thread[DefaultDispatcher-worker-2,5,main] hi hellow 第二个
testLaunch 中的  GlobalScope.launch 线程Thread[DefaultDispatcher-worker-1,5,main] hi hellow
我是最下面的数据
函数总耗时:2426

2.async asynchronous, does not block threads

/**
     * CoroutineScope
     * GlobalScope.async 异步 不阻塞线程
     * 返回 Deferred<T> 返回一个 Future 对象,该对象在全局执行上下文中运行。这意味着它将在应用的整个生命周期中运行,不受应用上下文(如生命周期方法)的影响。
     * 用途 :主要用于创建全局的异步任务,这些任务在应用的整个生命周期中运行
     * 生命周期:与应用的生命周期相同,除非你明确地取消了它
     * 并发性:允许你创建全局的异步任务,这些任务可以在应用的整个生命周期中并发运行
     * 取消:Future 对象可以通过调用 Future.cancel() 方法来取消
     * 性能和资源使用:在全局执行上下文中运行,所以可能会影响应用的性能和资源使用。特别是当有大量全局异步任务时,这可能会成为一个问题
     * 隔离性:在全局执行上下文中运行的,因此没有隔离性。这意味着不同的异步任务可以相互影响
     * 错误处理:错误可以通过 Future 的异常处理机制来处理
     */
    fun testAsync() {
        val time: Long = measureTimeMillis {
            GlobalScope.async {
                Thread.sleep(1000)
                println("testLaunch 中的  GlobalScope.async 线程${Thread.currentThread()} hi hellow")
            }
            GlobalScope.async {
                Thread.sleep(1000)
                println("testLaunch 中的  GlobalScope.async2 线程${Thread.currentThread()} hi hellow 第二个")
            }
            //停一下等待 上面线程执行完成
            Thread.sleep(2200)
            println("我是最下面的数据")
        }
        println("函数总耗时:$time")
    }

operation result:

testLaunch 中的  GlobalScope.async 线程Thread[DefaultDispatcher-worker-1,5,main] hi hellow
testLaunch 中的  GlobalScope.async2 线程Thread[DefaultDispatcher-worker-2,5,main] hi hellow 第二个
我是最下面的数据
函数总耗时:2487

3.runBlocking blocking thread

/**
     *runBlocking ,阻塞线程
     * 顺序执行
     */
    fun testRunBlocking(){
        val time = measureTimeMillis {
            runBlocking {
                println("testRunBlocking 中的  runBlocking 线程${Thread.currentThread()} hi hellow")
                Thread.sleep(2000)
                println("testRunBlocking 中的  runBlocking2 线程${Thread.currentThread()} hi hellow 第二个")
                //延迟 毫秒
                delay(3000)
            }
            println("我是外面的数据")
        }
        println("函数总耗时:$time")
    }

operation result:

testRunBlocking 中的  runBlocking 线程Thread[main,5,main] hi hellow
testRunBlocking 中的  runBlocking2 线程Thread[main,5,main] hi hellow 第二个
我是外面的数据
函数总耗时:5194

4.cancel and join

 /**
     *runBlocking 会等待内部协程执行完毕才结束
     */
    fun testCancelJoin() = runBlocking {
        val time = measureTimeMillis {
            // launch 异步不阻塞
            val jobL1: Job = launch {
                println("testCancelJoin 中的 jobL1 launch1 线程${Thread.currentThread()} hi hellow")
            }
            // Job
            val jobL2: Job = launch {
                println("testCancelJoin 中的 jobL2 launch2 线程${Thread.currentThread()} hi hellow 第二个")
            }

            //取消jobL2协程执行.
            jobL2.cancel()

            //jobL2,并返回主协程
//            jobL2.cancelAndJoin()

            //Deferred<T>   async 异步不阻塞
            val defA1: Deferred<Unit> = async {
                //repeat 执行指定次数的给定函数操作。
                //当前迭代的从零开始的索引作为参数传递给操作。
                repeat(10) {
                    println("testCancelJoin 中的defA1  async1 线程${Thread.currentThread()} $it hi hellow")
                    delay(200)
                }
            }
            // //取消defA1协程
//            defA1.cancel()

            //取消defA1协程,并返回主协程
//            defA1.cancelAndJoin()

            //需要等待 defA1 协程执行结束 才会执行下面代码
            defA1.join()

            val defA2: Deferred<Unit> = async {
                println("testCancelJoin 中的defA2  async2 线程${Thread.currentThread()} hi hellow")
            }



            println("我是外面的数据 线程${Thread.currentThread()}")
        }
        println("函数总耗时:$time")
}

operation result:

testCancelJoin 中的 jobL1 launch1 线程Thread[main,5,main] hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 0 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 1 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 2 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 3 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 4 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 5 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 6 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 7 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 8 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 9 hi hellow
我是外面的数据 线程Thread[main,5,main]
函数总耗时:2506
testCancelJoin 中的defA2  async2 线程Thread[main,5,main] hi hellow

5.withTimeout


    /** runBlocking 阻塞的
     * withTimeout 超时自动取消内部协程
     */
    fun testTimeOut() = runBlocking {
        val time = measureTimeMillis {
            //超时自动取消内部协程 会抛出异常
            withTimeout(3000) {
                //repeat 执行指定次数的给定函数操作。
                //当前迭代的从零开始的索引作为参数传递给操作。
                repeat(200) {
                    println("withTimeout repeat当前迭代的线程 ${Thread.currentThread()} -- $it")
                    delay(300)
                }

                println("withTimeout 的线程 ${Thread.currentThread()} ")
            }

            //超时自动取消内部协程 不会抛出异常
//            withTimeoutOrNull(2000){
//                repeat(200){
//                    println("withTimeoutOrNull repeat当前迭代的线程 ${Thread.currentThread()} -- $it")
//                    delay(300)
//                }
//            }
        }


    }

operation result:

withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 0
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 1
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 2
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 3
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 4
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 5
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 6
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 7
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 8
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 9
Exception in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 3000 ms
	at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:184)
	at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:154)
	at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.common.kt:508)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:108)
	at java.base/java.lang.Thread.run(Thread.java:833)

6.await

    /**runBlocking 阻塞的 等待协程执行完毕 这个方法才会结束
     * await() 拿结果
     * getCompleted()   拿结果
     */
    fun testAwait() = runBlocking {
        val time = measureTimeMillis {
            //Deferred<T>   async 异步不阻塞
            val defA1: Deferred<Int> = async {
                println("testAwait 中的defA1  async1 线程${Thread.currentThread()} hi hellow")
                delay(2000)//延迟2秒
                100
            }
//            defA1.join()

            val defA2: Deferred<String> = async {
                println("testAwait 中的defA2  async2 线程${Thread.currentThread()} hi hellow")
//                delay(3000)//延迟3秒
//                "hi hello"
                //调用挂起方法
                getData()
            }
//            defA2.join()
            println("结果:线程${Thread.currentThread()} --- ${defA1.await()}  --${defA2.await()} ")
//            println("结果:线程${Thread.currentThread()} --- ${defA1.getCompleted()}  --${defA2.getCompleted()} ")
        }
        println("函数总耗时:$time")
    }

    // 声明一个 suspend 方法  挂起方法
    suspend fun getData(): String {
        println("testAwait 中的 getData()线程${Thread.currentThread()} hi hellow")
        delay(1000) // 模拟一个长时间运行的操作
        return "Hello, World!"
    }

operation result:

testAwait 中的defA1  async1 线程Thread[main,5,main] hi hellow
testAwait 中的defA2  async2 线程Thread[main,5,main] hi hellow
testAwait 中的 getData()线程Thread[main,5,main] hi hellow
结果:线程Thread[main,5,main] --- 100  --Hello, World! 
函数总耗时:2131

Guess you like

Origin blog.csdn.net/jiayou2020527/article/details/135374823