Kotlin 进阶版 协程

kotlin是协程的一种实现

  1. Dispatchers.IO:适用于执行磁盘或网络 I/O 操作的调度器,例如文件读写、网络请求等。在 Android 中,Dispatchers.IO 会使用一个专门的线程池来处理这些操作,以防止阻塞主线程。

  2. Dispatchers.Main:适用于处理与 UI 相关的操作的调度器,例如更新 UI 界面、响应用户输入等。在 Android 中,Dispatchers.Main 通常会将协程切换到主线程执行,确保 UI 操作在主线程中进行。

  3. Dispatchers.Unconfined:不对协程的执行环境做任何限制,使用该调度器时,协程将在调用它的线程中执行,直到遇到挂起函数为止,之后会在恢复执行时继续在之前的线程中执行。

  4. Dispatchers.Default:适用于执行 CPU 密集型任务的调度器,例如算法计算、数据处理等。Dispatchers.Default 在 Android 中会使用一个共享的线程池来处理这些任务,以便在多个协程之间进行合理的调度。

 

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

fun main() {
    //IO线程  超大密集的计算 Default

    /**
     * IO
     * Default
     * Main
     *
     */
    CoroutineScope(Dispatchers.IO).launch {
        test()
//        withContext(Dispatchers.Main){
//
//        }
    }
    println("主线程")
    Thread.sleep(2000)
}

/**
 * 协程代码块
 */
suspend fun test() {
    println("协程开始")
    delay(1000)
    println("协程结束")
}

1.runBlocking

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

fun main() {
    println("hello")
    //如果给的参数第一个为空,那么它会去找到这个协程外面调用它的这个线程 一般在写Test的时候才用一下 阻塞式协程
    val i = runBlocking (Dispatchers.IO){
        //如果制定了了调度器,它会被分配到另一个线程上面执行 ,但也可以阻塞当前线程
        println(
            Thread.currentThread().name
        )
        //这个协程会阻塞当前线程 同步执行
        delay(2000)
        1
    }
    println(
        Thread.currentThread().name
    )
    println("world $i ")
}

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    println("hello")
    //如果给的参数第一个为空,那么它会去找到这个协程外面调用它调度器 一般在写Test的时候才用一下 阻塞式协程
    //会等里面所有的协程执行完了,才会释放主线程
    val i = runBlocking (Dispatchers.IO){
        //如果制定了了调度器,它会被分配到另一个线程上面执行 ,但也可以阻塞当前线程
        println(
            Thread.currentThread().name
        )

        println(this)
        //this :BlockingCoroutine 可以再次开启一个协程
        val job = this.launch {
            //这个开启的协程不会阻塞当前线程,异步
            println(
                //没有指定 ,他会默认继承上面所在的调度器 被这个调度器管理的线程池的线程去执行
                Thread.currentThread().name
            )
            delay(5200)
        }

        println(job.isActive)
        println(job.cancel())
        println(job.isActive)
        println("延迟了吗")


        //这个协程会阻塞当前线程 同步执行
        delay(2000)
        1
    }
    println(
        Thread.currentThread().name
    )
    println("world $i ")


    /**
     * 总结
     * IO 网络请求 数据库
     * default 密集型数据处理操作 数据计算
     * main UI操作
     *
     */
}

 

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

fun main() {
    println("hello")
    val i = runBlocking (Dispatchers.IO){

            request{
                //手动切换到UI线程里
                withContext(Dispatchers.Main){
                    //修改UI
                

                }

            }

    }
    println("world $i")
}

suspend fun request(finish:suspend ()->Unit){
    delay(3000)
    println("网络请求成功")
    finish()
}

好处:不会出现在其他的线程里出现UI报错的问题了

2.GlobalScope

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

fun main() {
    val launch = GlobalScope.launch { //全局指的是整个程序的生命周期 就算Activity销毁了这个GlobalScope还是存在的
        // 这样可能会造成一些奇怪的问题
        delay(3000)
        println("hello")
    }//这不是阻塞当前线程的一个协程操作
    val launch1 = GlobalScope.launch {

    }

    println(launch===launch1)
    //不能调用cancel 方法,因为作用域是整个生命周期的,不能由我们来管理

    while (true);
}

3.CoroutineScope

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

fun main() {
    //推荐使用这个  不是全局的
    val coroutineScope1 = CoroutineScope(Dispatchers.Default)


    coroutineScope1.launch {
       delay(3000)

        println("结束")
    }
    coroutineScope1.launch {
        delay(3000)

        println("结束")
    }
    coroutineScope1.cancel() //可以手动进行取消,不会涉及到全局 整个程序的生命周期
    Thread.sleep(4000)
    println("主线程结束")
}

4.Launch分析

4.1 第一个参数 context: CoroutineContext

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.Job

import kotlinx.coroutines.launch
import kotlinx.coroutines.newCoroutineContext
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

@OptIn(ExperimentalStdlibApi::class)
fun main() {


    val runBlocking = runBlocking {
        val launch = this.launch(Dispatchers.Default) {
            println(this.coroutineContext.get(CoroutineDispatcher).toString())//拿到调度器信息

        }
        println(launch)
        launch
    }//是同一个对象
    println(runBlocking)

}


package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.Job

import kotlinx.coroutines.launch
import kotlinx.coroutines.newCoroutineContext
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

@OptIn(ExperimentalStdlibApi::class)
fun main() {


    val runBlocking = runBlocking(Dispatchers.IO) {
        val launch = this.launch (Dispatchers.Default){
            println(this.coroutineContext.get(CoroutineDispatcher).toString())//拿到调度器信息

        }
        println(launch)
        launch
    }//是同一个对象
    println(runBlocking)

}


 

4.2 第二个参数 start:CoroutineStart

 

  1. default 是协程默认的启动方式  由默认协程调度去调度 决定在哪一个线程上面执行

    val runBlocking = runBlocking(Dispatchers.IO) {
        val launch = this.launch{
            println("hello")
            delay(1000)
            println("end")
        }
        //异步就会走到下面,end不执行
        launch.cancel()
    }//是同一个对象

2. ATOMIC

    val runBlocking = runBlocking(Dispatchers.IO) {
        val launch = this.launch(start = CoroutineStart.ATOMIC){//ATOMIC是一个立即启动的过程 把执行此协程的优先级调上去
            
            println("hello")
            delay(1000)
            println("end")
        }
        //异步就会走到下面,end不执行
        launch.cancel()
    }//是同一个对象

3.LAZY 可以自己控制何时启动

 val runBlocking = runBlocking(Dispatchers.IO) {
        val launch = this.launch(start = CoroutineStart.LAZY){//LAZY 可以自己控制何时启动
            println("hello")
            delay(1000)
            println("end")
        }
        println("先打印,在启动")
        //异步就会走到下面,end不执行
        launch.start()
    }//是同一个对象

5. async详解

  this.async(Dispatchers.Default, start = CoroutineStart.DEFAULT){

                println("进来异步了")
                delay(1000)
                println("被卡住了")


        }

1.获取值方法1

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay

fun main() {
    val coroutineScope = CoroutineScope(Dispatchers.Default)

    val async = coroutineScope.async(Dispatchers.Default, start = CoroutineStart.DEFAULT) {

        println("进来异步了")
        delay(1000)
        println("被卡住了")

        "协程异步返回值"
    }
        Thread.sleep(3000)
    val completed = async.getCompleted()
    println(completed)
}
package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

fun main() {

    runBlocking {
        val async = this.async {
            test1()
        }
        for (i in 0..10) {
            println("hello $i")
        }
        val await = async.await()

        println(await)



    }

}

suspend fun test1():Int{
    println("执行中")
    delay(3000)
    return 100
}

6.select函数 与 onAwait方法

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.selects.select

fun main() {

    runBlocking {
        val d = this.async {
            delay(2000)
            test1(1)
        }//同时启动的
        val c = this.async {
            test1(2)
        }//同时启动的

        //泛型是协程返回的类型
        //select可以等待多个协程的结束
        //select会阻塞当前的线程
        println(select<String> {
            c.onAwait.invoke {
                "c"  //it是协程返回值
            }
            d.onAwait.invoke {
                "d"
            }
            //谁先执行结束就返回谁
        })

        println("end")







    }

}

suspend fun test1(item:Int):Int{
    println("执行中$item")
    delay(3000)
    return 100
}

7. withContenxt

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

@OptIn(ExperimentalStdlibApi::class)
fun main() {
    runBlocking(Dispatchers.IO) {
        println(coroutineContext.get(CoroutineDispatcher).toString())
        val withContext = withContext(Dispatchers.Default) {
            //会对协程有一个阻塞  挂起就是阻塞的意思
            delay(2000)
            println(coroutineContext.get(CoroutineDispatcher).toString())
            //返回值就是lamda最后一行 ,并且结束以后会回到之前的那个协程上面继续执行
            "withContext result"
        }
        println(withContext)
        println(coroutineContext.get(CoroutineDispatcher).toString())
    }
}

package com.tiger.kotlincoroutine.coroutine

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

@OptIn(ExperimentalStdlibApi::class)
fun main() {
    //如果不想阻塞当前协程,那就重新开一个
    runBlocking(Dispatchers.IO) {
        println(coroutineContext.get(CoroutineDispatcher).toString())
      launch {
          val withContext = withContext(Dispatchers.Default) {
              //会对协程有一个阻塞  挂起就是阻塞的意思
              delay(2000)
              println(coroutineContext.get(CoroutineDispatcher).toString())
              //返回值就是lamda最后一行 ,并且结束以后会回到之前的那个协程上面继续执行
              "withContext result"
          }
          println(withContext)
      }


        println(coroutineContext.get(CoroutineDispatcher).toString())
    }
}

8.suspend关键字

协程就是任务代码块,有调度器进行线程分配执行此代码块,可以公用一个线程,异步执行代码块,也可以不是一个线程执行.

suspend 声明一个挂起函数,可以阻塞当前协程去执行代码块里的内容,主要是针对协程的。

因为 Thread.sleep 是停止线程的,协程是在线程上面跑的。

delay是延迟当前协程,不停线程,其他协程在此线程上面跑的话,那么都会被停止

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/410098.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

幻兽帕鲁服务器多少钱?有买过的吗?

幻兽帕鲁服务器多少钱&#xff1f;太卷了&#xff0c;降价到24元1个月&#xff0c;阿里云4核16G10M游戏服务器26元1个月、149元半年&#xff0c;腾讯云4核16G游戏服务器32元、312元一年&#xff0c;华为云26元&#xff0c;京东云主机也是26元起。云服务器吧yunfuwuqiba.com给大…

[RCTF2015]EasySQL1 题目分析与详解

一、题目介绍&#xff1a; 1、题目来源&#xff1a; BUUCTF网址 2、题目介绍&#xff1a; 拿到flag。 二、解题思路&#xff1a; 我们发现题目首页有登录和注册账号两个选项&#xff0c;我们首先尝试注册账号&#xff0c;尝试注册username为admin的账号&#xff0c;输入密码…

这10款设计工具,助你轻松搞定主视觉设计!

我们浏览网站、App或其他数字产品时&#xff0c;页面或屏幕上最显著最重要的部分&#xff0c;比如设计风格、颜色、排版、图片和元素等信息&#xff0c;就是数字产品的主视觉&#xff0c;也是用户首次接触产品时最能直观感受的部分。 由此可见&#xff0c;主视觉设计有多重要&…

【大数据】Flink 内存管理(四):TaskManager 内存分配(实战篇)

《Flink 内存管理》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 4 篇文章&#xff1a; Flink 内存管理&#xff08;一&#xff09;&#xff1a;设置 Flink 进程内存Flink 内存管理&#xff08;二&#xff09;&#xff1a;JobManager 内存分配&#xff08;含实际…

PyTorch中Tensor(张量)数据结构内部观察

上图中是一个张量embeds&#xff0c;打开其内部存储空间&#xff0c;我们可以看到内部的构成。在PyTorch中&#xff0c;Tensor 具有许多属性和方法。以下是其中一些关键的属性和方法&#xff1a; 属性&#xff1a; H&#xff1a; 在标准的PyTorch API中并没有直接表示为 .H 的…

IO进程线程:共享内存

shmsnd.c #include<myhead.h> #define PAGE_SIZE 4096 //一页的大小 int main(int argc, const char *argv[]) {//1.创建key值key_t key-1;if((keyftok("/",k))-1){perror("ftok error");return -1;}printf("key%d\n",key);//2.通过key…

【计算机网络】传输层——TCP和UDP详解

文章目录 一. TCP和UDP简介二. UDP 协议详解1. UDP报文格式2. UDP的使用场景 三. TCP 协议详解1. TCP报文格式2. TCP协议的重要机制确认应答&#xff08;保证可靠传输的最核心机制&#xff09;超时重传连接管理&#xff08;三次握手、四次挥手&#xff09;&#xff01;&#xf…

C语言 int和unsigned int逻辑比较

文章目录 测试1、测试 CMP (int,int)2、测试 CMP (int ,unsigned int)3、测试 CMP (unsigned int ,unsigned int) 总结 测试 在IAR(8.40.2)平台下测试单片机为STM32F103ZET6 1、测试 CMP (int,int) //a -2,b 3 int test_fun(int a, int b) {if(a>b){return 1;}else{re…

[力扣 Hot100]Day35 LRU 缓存

题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否…

Linux7.9环境源码编译安装ffmpeg6.x

1.官网ffmpeg下载源码 https://ffmpeg.org/download.html#build-windows 2.未安装x264库则先安装配置 可以先查询x264库: whereis libx264 安装编译工具和依赖库&#xff1a; sudo yum install gcc make cmake mercurial git yasm pkgconfig autoconf automake libtool sudo…

【每日一题】938. 二叉搜索树的范围和-2024.2.26

题目&#xff1a; 938. 二叉搜索树的范围和 给定二叉搜索树的根结点 root&#xff0c;返回值位于范围 [low, high] 之间的所有结点的值的和。 示例 1&#xff1a; 输入&#xff1a;root [10,5,15,3,7,null,18], low 7, high 15 输出&#xff1a;32示例 2&#xff1a; 输入…

Python实用技巧:输出列表(list)的倒序/逆序的几种方法

Python实用技巧&#xff1a;输出列表&#xff08;list&#xff09;的倒序/逆序的几种方法 &#x1f4c5;2024年02月25日 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质…

力扣随笔之寻找重复数(中等287)

思路1&#xff1a;暴力解法&#xff0c;根据要求不修改数组且只用常量级O(1)的额外空间&#xff0c;我们写两层嵌套循环&#xff0c;寻找重复的数;可以解决部分问题&#xff0c;但会超出时间限制无论Java还是C; Java实现&#xff1a; class Solution {public int findDuplicat…

第四节:Vben Admin登录对接后端getUserInfo接口

系列文章目录 第一节&#xff1a;Vben Admin介绍和初次运行 第二节&#xff1a;Vben Admin 登录逻辑梳理和对接后端准备 第三节&#xff1a;Vben Admin登录对接后端login接口 第四节&#xff1a;Vben Admin登录对接后端getUserInfo接口 文章目录 系列文章目录前言一、回顾Vben…

Elastic Search的RestFul API入门:使用SQL查询ES

确实,Elasticsearch 中也支持 SQL 语法,但我们通常使用 DSL 进行 API 操作,很少有人用 SQL 进行 Elasticsearch 的操作。然而,如果你刚开始学习 Elasticsearch,这一节的内容可以帮助你更快地理解 Elasticsearch(前提是你已经熟悉 SQL)。通过 SQL 查询,你可以进行一些简…

HTTPS对HTTP的加密过程

1、HTTPS是在HTTP的基础上&#xff0c;引入了一个加密层&#xff08;SSL&#xff09;&#xff0c;对数据进行保护&#xff0c;HTTP 是明文传输的&#xff08;不安全&#xff0c;很可能会被运营商通过referer劫持&#xff0c;或者黑客通过修改链接来窃数据&#xff09; 2、加密…

数字人的未来:数字人对话系统 Linly-Talker + 克隆语音 GPT-SoVITS

&#x1f680;数字人的未来&#xff1a;数字人对话系统 Linly-Talker 克隆语音 GPT-SoVITS https://github.com/Kedreamix/Linly-Talker 2023.12 更新 &#x1f4c6; 用户可以上传任意图片进行对话 2024.01 更新 &#x1f4c6; 令人兴奋的消息&#xff01;我现在已经将强…

【数据结构】图——最短路径

最短路径问题&#xff1a;从在带权有向图G中的某一顶点出发&#xff0c;找出一条通往另一顶点的最短路径&#xff0c;最短也就是沿路径各边的权值总和达到最小。 最短路径分为图中单源路径和多源路径。 本文会介绍Dijkstra和Bellman-Ford解决单源路径的问题 Floyd-Warshall解…

实操 - openstack的自动化部署

一 、使用openstack自带的工具packstack部署allinone模式 此模式将所有的服务装在一个虚机中&#xff0c;用来测试 1.克隆一台虚拟机&#xff08;配置好七项&#xff09;virt-clone 2.下载openstack-packstack之前删除mariadb所有相关内容(可选项) #rpm -qa | grep mariad…

二叉树与堆

目录 1.树概念及结构 1.1树的概念 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树&#xff1a; 2.3 特殊的二叉树&#xff1a; 2.4 二叉树的性质 2.5 二叉树的…