美文网首页
第三十七节 协程二

第三十七节 协程二

作者: 最美下雨天 | 来源:发表于2018-06-03 18:51 被阅读6次

看几张图


image.png
image.png
image.png
image.png
image.png

协程原理
• 可以把耗时任务先挂起
• 等时间到了再从线程池中取出空闲的线程执行
• 但是必须是挂起函数才能挂起

挂起函数

关键字suspend

  • 挂起函数:可以被挂起执行 到时间之后从线程池中空闲的线程中恢复执行
  • 挂起函数必须通过suspend进行修饰
  • 挂起函数必须在协程中执行 或者在其他挂起函数中执行

协程的取消

import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>)= runBlocking {
    val job = launch {
        (1..10).forEach {
            println("打印$it")
            delay(500L)
        }
    }
    //定时3秒钟,调用cancel方法取消协程
    delay(3000L)
    //取消协程
    job.cancel()

    job.join()
}

输出:


image.png

协程的定时任务

import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking
import kotlinx.coroutines.experimental.withTimeout

fun main(args: Array<String>) = runBlocking {
    val job = launch {
        withTimeout(2000L) {
            (1..10).forEach {
                println("打印$it")
                delay(500L)
            }
        }
    }

    job.join()
}

输出:


image.png

取消失效

fun main(args: Array<String>) = runBlocking{
    val job = launch {
        (1..10).forEach {
            println("打印$it")
            Thread.sleep(500L)
        }
    }
    //定时2秒钟  停止协程
    delay(2000L)
    //取消协程
    job.cancel()//取消挂起  Thread.sleep是阻塞式函数,不是挂起函数

    job.join()
}

输出:


image.png

协程的状态

import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>)= runBlocking {
    val job = launch {
        (1..10).forEach {
            println("打印$it")
            delay(500L)
        }
    }
    //定时3秒钟  停止协程
    delay(3000L)
    //协程状态
    println("取消之前${job.isActive}")

    //取消协程
    job.cancel()

    println("取消之后${job.isActive}")


    job.join()
}

输出:


image.png

协程的返回值

import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.runBlocking

/**
 * 第一中启动协程方式:launch 没有返回值
 * 第二种启动协程方式:async 需要返回值就是用async
 */
fun main(args: Array<String>) = runBlocking{
    //Deferred 是job的子类
    val job1 = async { job1() }
    val job2 = async { job2() }
    val result1 = job1.await()//执行完协程之后才能获取到数据
    val result2 = job2.await()
    println(result1)
    println(result2)

}
suspend fun job1():String{
    println("开始执行job1")
    delay(1000L)
    println("执行了job1")
    return "job1"
}
suspend fun job2():String{
    println("开始执行job2")
    delay(1000L)
    println("执行了job2")
    return "job2"
}

输出:


image.png

协程的上下文

import kotlinx.coroutines.experimental.*

fun main(args: Array<String>)= runBlocking {
    //第一个代表协程上下文 指定协程代码在哪个线程池中运行 默认是通过Commpool实现的
    val job1 = launch {
        println("协程执行")
    }
    val job2 = launch(CommonPool) {
        println("协程执行")
    }
    val job3 = launch(Unconfined) {//运行在主线程中
        println("协程执行")
    }
    val job4 = launch(coroutineContext) {//运行在父协程的上下文中 当前运行在主线程中
        println("协程执行")
    }
    val job5 = launch(newFixedThreadPoolContext(5,"新线程")) {//自定义线程池执行
        println("协程执行")
    }
    job1.join()
    job2.join()
}

看结果额,很重要

image.png

我们以前在使用线程时,线程在执行过程中发送阻塞,再次执行时是在同一个线程,而协程不同,不一定是不是在同一个线程

相关文章

网友评论

      本文标题:第三十七节 协程二

      本文链接:https://www.haomeiwen.com/subject/cfzjsftx.html